這個有趣的C++系列打算展示一下使用C++寫代碼可以和其他主流語言一樣高效而有趣。在第二部分,我將向你展示使用C++從無到有的創建一個井字游戲。這篇文章,以及整個系列都是針對那些想學習C++或者對這個語言性能好奇的開發者。
許多年輕人想學習編程來寫游戲。C++是用的最多的用來寫游戲的語言,盡管在寫出下個憤怒的小鳥之前,需要學會很多的編程經驗。一個井子游戲是開始學習的 一個好選擇,事實上,在許多年前我開始學習C++後,他是我寫的地一個游戲。我希望這篇文章可以幫助到那些還不熟悉C++的初學者和有經驗的開發者。
我使用的是Visual Studio 2012來寫這篇文章的源代碼。
游戲介紹
如果你沒有玩過井字游戲或者並不熟悉這個游戲,下面是來自維基百科的描述.
井字游戲 (或者"圈圈和叉叉",Xs and Os) 是一個兩人的紙筆游戲,兩個人輪流在3X3的網格內畫圈和叉. 當一名玩家放置的標志在水平,垂直或者對角線上成一條線即獲得勝利.這個游戲也可以人機對戰,先手不固定.
創建這個程序的時候有2個關鍵的東西:程序的邏輯和程序的UI界面. 有許多在windows中創建用戶UI的方法, 包括 Win32 API, MFC, ATL, GDI+, DirectX, etc. 在這篇文章中,我將展示使用多種技術來實現同一個程序邏輯. 我們將新建2個應用, 一個使用 Win32 API 另一個使用 C++/CX.
如果一個玩家在網格上放下一個標記時,遵循幾個簡單的規則,那他就可以玩一個完美的游戲意味著贏或者平局)。在Wikipedia上寫有這些規則,在裡面你也可以找到先手玩家的最優策略。
在xkcd drawing上 有先手和後手玩家的最優策略。盡管有幾個錯誤在幾種情況下沒有走必勝的步驟,至少在一個情況下丟失了一個X標記),我將使用這個版本作為游戲策略修復 了那些我能找到的錯誤)。記住電腦總是玩一個完美的游戲。如果你實現了這樣一個游戲,你可能也想讓用戶贏,這種情況下你需要一個不同的方法。當對本文的目 的,這個策略應該足夠了。
提出的第一個問題是在C++程序中用什麼數據結構來表示圖像的模型。這可以有不同的選擇,比如樹、圖、數組或者位字段如果真有人對內存消耗很在意)。網 格有9個單元,我選擇的最簡單的使用對每個單元使用一個包含9個整數的數組:0表示空的單元,1表示單元被標記為X,2表示單元被標記為O。讓我們看下圖 以及它將被如何編碼。
這幅圖可以這麼理解:
記住這個我們就可以開始在程序中對其編碼了。我們將使用一個std::array來表示一個9格板。這是個固定大小的容器,在編譯時就已知的大小,在連續的內存區域存儲元素。為了避免一遍又一遍的使用相同數組類型,我將定義一個別名來簡化。
- #include <array>
- typedef std::array<char, 9> tictactoe_status;
上面描述的最優策略用這樣的數組隊列另一個數組)來表示。
- tictactoe_status const strategy_x[] =
- {
- {1,0,0,0,0,0,0,0,0},
- {1,2,0,0,1,0,0,0,0},
- {1,2,2,0,1,0,0,0,1},
- {1,2,0,2,1,0,0,0,1},
- // ...
- };
- tictactoe_status const strategy_o[] =
- {
- {2,0,0,0,1,0,0,0,0},
- {2,2,1,0,1,0,0,0,0},
- {2,2,1,2,1,0,1,0,0},
- {2,2,1,0,1,2,1,0,0},
- // ...
- };