我與很多學生和專業開發人員交談過,他們經常想要啟動一個業余項目,但不確定要構建什么。下面是一些教會了我很多東西的軟件項目。事實上,它們很棒,因為您可以多次構建它們并每次都能學到新東西。因此,每當我不知道要構建什么或者我想學習一種新的編程語言或框架時,我都會從以下之一開始:
- Text editor 文本編輯器
- 2D game - Space Invaders
2D 游戲 - 太空侵略者 - Compiler - Tiny BASIC
編譯器 - Tiny BASIC - Mini operating system 迷你操作系統
- Spreadsheet (hard!) 電子表格(很難!)
- Video game console emulator (hard!)
視頻游戲控制臺模擬器(很難!)
Text Editor 文本編輯器
我們每天都會使用文本編輯器,但是你知道它到底是如何工作的嗎?忽略您最喜歡的編輯器具有的所有奇特功能,您將如何實現支持可移動文本光標以及選擇、插入和刪除文本的文本框?不,您不能使用您最喜歡的 GUI 框架中的內置文本框組件!
最大的挑戰是弄清楚如何將文本文檔存儲在內存中。我的第一個想法是使用數組,但如果用戶在文檔末尾以外的任何地方插入文本,那么它的性能會很糟糕。幸運的是,有一些很好的數據結構可以學習來解決這個問題。
另一個障礙是了解文本光標在流行編輯器中的行為方式。例如,如果我在光標位于文檔中間的情況下按向上箭頭鍵,光標會移動到哪里?同一個專欄?如果該線較短則不會。繼續往上按。一旦一行足夠長,光標將快速返回到原始列。事實證明,光標有該列的記憶,并試圖返回該列。正是這些細節我在嘗試實現之前從未注意到。

實現基本編輯器后,我挑戰您再實現兩個功能:撤消/重做和自動換行。以有效的方式實現撤消/重做讓我大吃一驚!我首先嘗試保留一系列先前的狀態,然后嘗試“備忘錄”模式,最后選擇“命令”模式。自動換行迫使您將文本行的視覺方面與記憶方面分開。
Things to learn: 學習內容:
- Data structures for storing the text: array, rope, gap buffer, piece table.
用于存儲文本的數據結構:數組、繩索、間隙緩沖區、片段表。 - Behavior and implementation of the text cursor.
文本光標的行為和實現。 - Design patterns for undo/redo: memento, command.
撤消/重做的設計模式:備忘錄、命令。 - Abstractions to separate the visual and memory aspects of the text.
用于分離文本的視覺和記憶方面的抽象。
Further reading: 進一步閱讀:
- Text Editor: Data Structures (web)
文本編輯器:數據結構(網絡) - Design and Implementation of a Win32 Text Editor (web)
Win32文本編輯器的設計與實現(web) - Data Structures and Algorithms in Java (Amazon)
Java 中的數據結構和算法(亞馬遜)
2D game - Space Invaders
2D 游戲 - 太空侵略者
即使是最簡單的游戲也需要一些獨特的數據結構和設計模式。這里的想法是從頭到尾實現一個定義明確的游戲,而不會陷入其他有趣的東西(例如游戲設計和藝術)。另外,最好使用準系統 2D 圖形庫(例如 SDL、SFML、PyGame),而不是會隱藏所有有趣部分的大型游戲引擎。

首先,您必須學習在屏幕上繪圖。我不知道這是如何運作的。實際上,您正在清除屏幕,然后快速連續地繪制屏幕的每個部分,每秒多次,以創建對象正在移動的效果。
其次,您將了解有關游戲循環的所有內容。游戲在繪圖、獲取用戶輸入和處理游戲邏輯之間有效地循環。
第三,您將學習如何處理用戶輸入。我從來沒有注意到最初按下、按住和釋放按鍵或鼠標按鈕的微妙之處,更不用說處理雙擊之類的事情了。您多久檢查一次用戶輸入?如果你不斷地檢查,那就意味著游戲的其余部分被凍結了!
第四,您將學習如何創建和管理所有游戲對象及其狀態。例如,如何生成動態數量的敵人?工廠模式有很大幫助。
第五,您將學習如何應用游戲的邏輯。子彈位置什么時候更新?何時會有更多敵人出現在屏幕上?你怎么知道敵人何時被消滅?比賽什么時候結束?在制作游戲之前我從未使用過模運算符,但它散布在我的游戲代碼中。
一旦你讓基本的游戲運行起來,添加一個標題屏幕菜單、一個游戲結束屏幕,確保游戲即使在不同的計算機上也以相同的速度運行,并探索如何使用人工智能實現更有趣的敵人。還不夠嗎?添加著色器效果、聲音和在線多人游戲!
Things to learn: 學習內容:
- Drawing to the screen.
繪制到屏幕上。 - Handling user input. 處理用戶輸入。
- Game loop. 游戲循環。
- Creating and managing a dynamic number of objects (e.g., factory pattern).
創建和管理動態數量的對象(例如工廠模式)。 - State machines for enemy AI.
敵方人工智能的狀態機。 - Playing sound. 播放聲音。
- Using shaders. 使用著色器。
- Networking for online features.
網絡在線功能。
Further reading: 進一步閱讀:
- Game Programming Patterns (Amazon, web)
游戲編程模式(亞馬遜、網絡) - Data Structures for Game Programmers (Amazon)
游戲程序員的數據結構(亞馬遜) - Programming Game AI by Example (Amazon)
通過示例進行游戲 AI 編程(亞馬遜) - The 8 lessons I learned from releasing 8 video games (web)
我從發布 8 個視頻游戲中學到的 8 個教訓(網頁版)
Compiler - Tiny BASIC
編譯器 - Tiny BASIC
我參與過的最令人大開眼界的項目是編譯器。即使是現在,如果我周日下午有空來做一些編碼,很可能它是一個編譯器。當你創造出一些東西并讓其他人能夠創造出更多東西時,這種感覺真是太棒了。通過實現一個,我必須了解更多關于編譯器的復雜性,這是我通常永遠不會想到的(例如,表達式何時進行隱式類型轉換)。
我建議從頭開始為一種非常小的類似 BASIC 的語言(請參閱 Tiny BASIC)編寫編譯器,然后編譯為您熟悉的任何其他語言。例如,您可以用 Python 編寫一個輸出 C# 代碼的 Tiny BASIC 編譯器。它不必輸出匯編或C!避免這些將使您專注于編譯器本身。

第一個障礙是弄清楚如何對輸入代碼進行詞法分析(或標記化)。然后您將解析代碼,即檢查輸入的結構并生成代碼的樹表示。遞歸下降解析技術很漂亮!接下來,您將從語義上檢查輸入,確保代碼有意義并且遵循類型規則。最后,您可以生成輸出!
該項目有大量現有資源可以幫助您,并且一個簡單的編譯器可以在幾天內完成。不要讓行話嚇到你。另外,您可以添加的內容是無限的!一旦基本編譯器開始工作,您就可以添加標準庫(在 PeayBASIC 中我添加了簡單的 2D 圖形功能)、優化過程并改進錯誤消息。最后,你應該用你自己的語言編寫一些示例程序來向世界炫耀!
Things to learn: 學習內容:
- Lexical analysis 詞法分析
- Syntactic analysis 句法分析
- Recursive descent parsing
遞歸下降解析 - Abstract syntax tree 抽象語法樹
- Semantic analysis 語義分析
- Optimization passes 優化通過
- Code generation 代碼生成
Further reading: 進一步閱讀:
- My tutorial: Let's make a Teeny Tiny compiler (web)
我的教程:讓我們制作一個 Teeny Tiny 編譯器(網絡) - Crafting Interpreters (Amazon, web)
- Write an Interpreter in Go (Amazon)
用 Go 編寫解釋器(亞馬遜) - Let's Build a Compiler (web)
讓我們構建一個編譯器(網絡) - PeayBASIC source code (GitHub)
PeayBASIC 源代碼 (GitHub)
Mini Operating System 迷你操作系統
多年來,我發現自己將操作系統的基本概念應用到了各種領域,例如游戲,甚至人類行為的預測模型。在課堂環境中,操作系統使用的算法和數據結構可能看起來抽象或無用,但它們確實很有用。實施操作系統還幫助我更多地了解幕后發生的事情。

由于它依賴于硬件,因此有一些學習曲線和一些入門障礙。但是,通過閱讀書籍或教程,您應該能夠獲得一個可以運行您自己的程序的可啟動操作系統。我強烈推薦我同事的免費在線書籍《使用 Rust 制作 RISC-V 操作系統》。
Things to learn: 學習內容:
- Cross compiling 交叉編譯
- Bootloading 引導加載
- BIOS interrupts BIOS 中斷
- x86 modes x86 模式
- Memory management and paging
內存管理和分頁 - Scheduling (e.g., round robin)
調度(例如,循環) - File systems (e.g., FAT)
文件系統(例如 FAT)
Further reading: 進一步閱讀:
- OSDev.org's wiki of resources (web)
OSDev.org 的 wiki 資源(網絡) - Making a RISC-V Operating System using Rust (web)
使用 Rust 制作 RISC-V 操作系統 (web) - Operating System Concepts (Amazon)
操作系統概念(亞馬遜)
對你來說還不夠困難嗎?嘗試這兩個項目:
Spreadsheet 電子表格
電子表格應用程序(例如 Excel)將文本編輯器的一些挑戰與編譯器的挑戰結合在一起。您必須學習如何表示內存中的單元格內容并實現用于方程的編程語言的解釋器。
Further reading: 進一步閱讀:
- Directed acyclic graph (web)
有向無環圖(網絡) - Reactive programming paradigm (web)
響應式編程范式(網絡) - Spreadsheet Implementation Technology (Amazon)
電子表格實施技術(亞馬遜)
Video game console emulator
視頻游戲控制臺模擬器
為視頻游戲控制臺編寫模擬器(或虛擬機)將編寫編譯器、操作系統和游戲引擎的挑戰結合在一起。用自己的模擬器玩一下別人制作的真實游戲,真是太有成就感了!
模擬真實的視頻游戲控制臺意味著編寫一個虛擬機,假裝其功能與實際的 CPU 和其他硬件組件一樣。這允許您使用模擬器運行專為視頻游戲控制臺設計的游戲。
我建議首先模擬 CHIP-8,這是一個簡單的虛構控制臺,然后再轉向真正的視頻游戲控制臺。 NES、SNES、Gameboy 和 Gameboy Advance 都非常易于模擬,已經有大量文檔和開源模擬器,盡管它們都有自己的怪癖以使事情變得有趣(例如,某些游戲可能依賴于未記錄的錯誤) /特定硬件的功能)。還有PICO-8,它已經成為一款非常賺錢的“幻想”游戲機。
Further reading: 進一步閱讀:
- Writing a Chip-8 emulator (web)
編寫 Chip-8 模擬器(網絡) - JavaScript Chip-8 Emulator (Wayback Machine)
JavaScript Chip-8 模擬器(時光機) - How to Emulate a Game Boy in Rust (Wayback Machine)
如何在 Rust 中模擬 Game Boy(時光機) - PyBoy source code (GitHub)
PyBoy 源代碼 (GitHub)
如果您有任何其他項目想法,請告訴我!以下是來自 Hacker News、Reddit、Twitter 和我收到的電子郵件的建議列表:
- Database from scratch 數據庫從頭開始
- Ray tracer 射線追蹤器
- MS Paint clone
- Vector graphics editor 矢量圖形編輯器
- Image decoder 圖像解碼器
- Chatroom web app 聊天室網絡應用程序
- Digits of pi calculator
圓周率計算器的位數 - Common terminal utilities (e.g., grep)
常見的終端實用程序(例如 grep) - FTP client and server
FTP 客戶端和服務器
posted on
浙公網安備 33010602011771號