純C++遊戲程式設計: Tic-Tac-Toe(三連棋遊戲)的實現
這是在《通過遊戲程式設計實戰——教新手學C++程式設計》上看到的一個小遊戲,感覺不錯,適合新手學習C++,所以貼出來一起和大家分享!
完整程式碼見連結:http://download.csdn.net/detail/rehongchen/4586263 (可在VC、CFree下成功執行)
遊戲規則:
雙方輪流在一個九個方格的棋盤上畫十字(X)或圓圈(O),以所畫的三個記號成直、橫、斜線相連者為勝。
在計算機上實現,在螢幕上會顯示如下窗格:
0 | 1 | 2
---------
3 | 4 | 5
---------
6 | 7 | 8
玩家通過選擇上面的數字確定選擇的位置,用X表示,計算機用O表示。
建立函式列表:
函式 | 描述 |
void instructions(); | 顯示遊戲操作指南 |
char askYesNo(string question); |
接受一個問題,返回“y”或“n” |
int askNumber(string question, int high, int low = 0); | 詢問一定範圍內的數字。接受一個問題、一個範圍上限和一個範圍下限。返回low到high之間的數字 |
char humanPiece(); | 確定玩家的棋子。返回X或O |
char opponent(char piece); | 返回給定棋子的對應棋子。 |
void displayBoard(const vector<char>& board); | 在螢幕上顯示當前棋盤。 |
char winner(const vector<char>& board); | 確定遊戲的勝者。返回X、O、或T(和棋)或N(還沒有哪一方勝出) |
bool isLegal(const vector<char>& board, int move); | 判斷輸入的數字是否合法 |
int humanMove(const vector<char>& board, char human); | 獲取人類玩家的下棋。接受一個棋盤與人類玩家的棋子作為引數,返回玩家下棋的數字位置。 |
int computerMove(vector<char> board, char computer); | 獲取計算機玩家的下棋。接受一個棋盤與人類玩家的棋子作為引數,返回玩家下棋的數字位置。 |
void announceWinner(char winner, char computer, char human); | 宣佈最後結果。 |
下面從程式碼中分析C++語法和程式設計正規化:
// Tic-Tac-Toe
// Plays the game of tic-tac-toe against a human opponent
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// global constants
const char X = 'X';
const char O = 'O';
const char EMPTY = ' ';
const char TIE = 'T';
const char NO_ONE = 'N';
// function prototypes
void instructions();
char askYesNo(string question);
int askNumber(string question, int high, int low = 0); //注:low預設為0
char humanPiece();
char opponent(char piece);
void displayBoard(const vector<char>& board);
char winner(const vector<char>& board);
bool isLegal(const vector<char>& board, int move);
int humanMove(const vector<char>& board, char human);
int computerMove(vector<char> board, char computer);
void announceWinner(char winner, char computer, char human);
// main function
int main()
{
int move;
const int NUM_SQUARES = 9;
vector<char> board(NUM_SQUARES, EMPTY);
instructions();
const char human = humanPiece(); //確定人類是否第一步走棋,返回y或n
const char computer = opponent(human);
char turn = X; //與X相同的先走棋
displayBoard(board);
while (winner(board) == NO_ONE) //驗證是有勝出者
{
if (turn == human)
{
move = humanMove(board, human); //因為使用者走棋時可能不合法,所以需要在humanMove進行驗證,
board[move] = human;
}
else
{
move = computerMove(board, computer); //計算機走棋時不需驗證合法性,但需完成智慧走棋
board[move] = computer;
}
displayBoard(board);
turn = opponent(turn); //用以交換出棋順序
}
announceWinner(winner(board), computer, human); //宣佈結果:獲勝者或平手
return 0;
}
// functions
void instructions()
{
cout << "歡迎來到人機終極大戰: Tic-Tac-Toe.\n";
cout << "--where human brain is pit against silicon processor\n\n";
cout << "鍵入數字 0 - 8來選擇你選棋的位置. \n";
cout << "它會被如實的反映在下面的棋盤上:\n\n";
cout << " 0 | 1 | 2\n";
cout << " ---------\n";
cout << " 3 | 4 | 5\n";
cout << " ---------\n";
cout << " 6 | 7 | 8\n\n";
cout << "準備好了嗎?人類, 這場大戰馬上開始!\n\n";
}
char askYesNo(string question)
{
char response;
do
{
cout << question << " (y/n): ";
cin >> response;
} while (response != 'y' && response != 'n');
return response;
}
int askNumber(string question, int high, int low)
{
int number;
do
{
cout << question << " (" << low << " - " << high << "): ";
cin >> number;
} while (number > high || number < low); //直到獲得合法結果(0-8)才能退出迴圈
return number;
}
char humanPiece() //確定人類第一步走棋
{
char go_first = askYesNo("你確定你第一步走棋?");
if (go_first == 'y')
{
cout << "\n好吧,讓你先來,你走棋.\n";
return X;
}
else
{
cout << "\n你的勇氣欠佳... 我先走棋.\n";
return O;
}
}
char opponent(char piece) //返回對手走棋標誌
{
if (piece == X)
{
return O;
}
else
{
return X;
}
}
void displayBoard(const vector<char>& board) //注意:這裡接收棋盤的引用,展示當前棋盤佈局
{
cout << "\n\t" << board[0] << " | " << board[1] << " | " << board[2];
cout << "\n\t" << "---------";
cout << "\n\t" << board[3] << " | " << board[4] << " | " << board[5];
cout << "\n\t" << "---------";
cout << "\n\t" << board[6] << " | " << board[7] << " | " << board[8];
cout << "\n\n";
}
char winner(const vector<char>& board) //表示棋盤的向量是通過常量引用傳遞(const vector<char>&)的,
{ //傳遞引用非常高效,且向量被保護起來,防止任何修改
//列出所有可能勝出的情況
const int WINNING_ROWS[8][3] = { {0, 1, 2},
{3, 4, 5},
{6, 7, 8},
{0, 3, 6},
{1, 4, 7},
{2, 5, 8},
{0, 4, 8},
{2, 4, 6} };
const int TOTAL_ROWS = 8;
// if any winning row has three values that are the same (and not EMPTY),
// then we have a winner
//如果有任意一行上的三個內容均相同(但不為EMPTY)
//那麼就有一方勝出
for(int row = 0; row < TOTAL_ROWS; ++row)
{
if ( (board[WINNING_ROWS[row][0]] != EMPTY) &&
(board[WINNING_ROWS[row][0]] == board[WINNING_ROWS[row][1]]) &&
(board[WINNING_ROWS[row][1]] == board[WINNING_ROWS[row][2]]) )
{
return board[WINNING_ROWS[row][0]]; //返回第一個棋子的位置,也就是返回“X”或“O”
}
}
// since nobody has won, check for a tie (no empty squares left)
//如果沒有一方勝出,看是否是平手
if (count(board.begin(), board.end(), EMPTY) == 0)
return TIE;
// since nobody has won and it isn't a tie, the game ain't over
//未見分曉
return NO_ONE;
}
inline bool isLegal(int move, const vector<char>& board)
{
return (board[move] == EMPTY);
}
int humanMove(const vector<char>& board, char human)
{
int move = askNumber("你打算選哪個位置?", (board.size() - 1));
while (!isLegal(move, board))
{
cout << "\n這個位置已經有棋子佔據了, 愚蠢的人類.\n";
move = askNumber("你打算選哪個位置?", (board.size() - 1));
}
cout << "好吧...\n";
return move;
}
int computerMove(vector<char> board, char computer)
{
unsigned int move = 0;
bool found = false;
//if computer can win on next move, that抯 the move to make
while (!found && move < board.size())
{
if (isLegal(move, board))
{
//try move
board[move] = computer;
//test for winner
found = winner(board) == computer;
//undo move
board[move] = EMPTY;
}
if (!found)
{
++move;
}
}
//otherwise, if opponent can win on next move, that's the move to make
if (!found)
{
move = 0;
char human = opponent(computer);
while (!found && move < board.size())
{
if (isLegal(move, board))
{
//try move
board[move] = human;
//test for winner
found = winner(board) == human;
//undo move
board[move] = EMPTY;
}
if (!found)
{
++move;
}
}
}
//otherwise, moving to the best open square is the move to make
if (!found)
{
move = 0;
unsigned int i = 0;
const int BEST_MOVES[] = {4, 0, 2, 6, 8, 1, 3, 5, 7};
//pick best open square
while (!found && i < board.size())
{
move = BEST_MOVES[i];
if (isLegal(move, board))
{
found = true;
}
++i;
}
}
cout << "我選擇的位置是: " << move << endl;
return move;
}
void announceWinner(char winner, char computer, char human)
{
if (winner == computer)
{
cout << winner << " 勝出!\n";
cout << "我早就預料到了, 人類, 事實證明,我才是最優秀的。\n";
cout << "計算機要比人類聰明!\n";
}
else if (winner == human)
{
cout << winner << "'s won!\n";
cout << "不不! 這不是真的! 你肯定耍花招了, 人類.\n";
cout << "但是不會又下一次了! 我,計算機,我發誓!\n";
}
else
{
cout << "平手了.\n";
cout << "這次是你幸運, 人類, 肯定是什麼操縱了這場比賽.\n";
cout << "同樣祝賀你... 因為這是你從沒有過的殊榮.\n";
}
}
如需轉載,請註明出處:http://blog.csdn.net/rehongchen/article/details/8005753相關文章
- Python實現三子棋小遊戲Python遊戲
- UE4純C++實現遊戲中快捷欄C++遊戲
- Minimax 和 Alpha-beta 剪枝演算法簡介,及以此實現的井字棋遊戲(Tic-tac-toe)演算法遊戲
- C++實用程式設計——坦克大戰小遊戲C++程式設計遊戲
- C++遊戲程式設計(一開篇)C++遊戲程式設計
- C++程式設計實現C++程式設計
- UE4純C++實現遊戲快捷欄之物品讀取C++遊戲
- 送給初學者的禮物:遊戲程式設計起源連載三(轉)遊戲程式設計
- 數獨遊戲的設計與實現遊戲
- html+css+JavaScript實現愛恩斯坦棋遊戲HTMLCSSJavaScript遊戲
- 採用α-β演算法實現井字棋遊戲演算法遊戲
- 《通過遊戲程式設計實戰教新手學C++程式設計》學習筆記遊戲程式設計C++筆記
- C語言實現小遊戲:五子棋C語言遊戲
- 原生JS+Canvas實現五子棋遊戲JSCanvas遊戲
- 程式設計師大神,C語言程式設計製作不一樣的五子棋小遊戲程式設計師C語言遊戲
- 純JS實現貪吃蛇遊戲 —— 可能是全網程式碼最優雅的實現。JS遊戲
- 轉自OGRE的一些遊戲程式設計的連結遊戲程式設計
- 聊一聊解謎遊戲的設計(六):劇情點綴“純”解謎遊戲遊戲
- 程式設計師玩的遊戲程式設計師遊戲
- C++原始碼遊戲程式設計---WinMain()函式集(轉)C++原始碼遊戲程式設計AI函式
- 遊戲設計的三大原則遊戲設計
- 【乾貨】遊戲介面設計 (三)資訊設計遊戲
- 人人都有遊戲夢——用cocos2d實現你的遊戲設計遊戲設計
- Java遊戲程式設計初步Java遊戲程式設計
- 魔方遊戲程式設計 (轉)遊戲程式設計
- DirectX5.0最新遊戲程式設計指南 DirectDraw篇 三、DirectDraw的要素(三) (轉)遊戲程式設計
- 三路國際象棋:非常有創意的棋類遊戲遊戲
- Java實現五子棋對戰小遊戲【完整版】Java遊戲
- 遊戲引擎介紹,架構,設計及實現遊戲引擎架構
- 通過三款遊戲,淺談遊戲BOSS戰的邏輯設計遊戲
- 【程式設計師的遊戲開發之路】 遊戲架構程式設計師遊戲開發架構
- Android群英傳-拼圖遊戲puzzle-程式碼設計和實現Android遊戲
- 07:蘑菇的前身-蘑菇小方塊的實現#python遊戲程式設計#紅傘傘Python遊戲程式設計
- [Erlang07] Erlang 做圖形化程式設計的嘗試:純Erlang做2048遊戲程式設計遊戲
- 物件導向的程式設計在遊戲開發中使用(三):三大特性物件程式設計遊戲開發
- Rust 程式設計,用連結串列實現棧Rust程式設計
- 送給初學者的禮物:遊戲程式設計起源連載二(轉)遊戲程式設計
- 遊戲《蔚藍山》教我的程式設計道理遊戲程式設計