バックギャモン
1. 実装アイデア
- 3*3 のチェス盤を定義し、スペースを使用して空きスペースを表し、* を使用してプレーヤーがプレイするチェスの駒を表し、# を使用してコンピューターがプレイするチェスの駒を表します。
- 出力メニュー、ユーザー入力 (1/0) に従ってゲームを選択するか、ゲームを終了します。
- ユーザーがゲームを選択すると、チェス盤が初期化され、プレイヤーが最初の駒をプレイできるようになり、コンピューターがランダムにチェスをプレイします。
- チェス盤を出力し、座標を尋ねます。
- ユーザーが入力した座標が正当であるかどうかを判断し、正当でない場合はエラーを表示して再入力します。
- 座標が不正な座標であるかどうか、つまりその位置がすでに占有されているかどうかを判断し、占有されている場合はエラーを表示して再入力します。
- ポジションが正当な場合は、対応する駒をボードに配置し、どちらかの側が勝つかどうかを確認します。
- ゲームが終了していない場合は、次のプレイヤーのターンに移ります。
- ゲームが終了したら、勝者を出力するか、引き分けかどうかを判断します。
- ゲームを続行するかゲームを終了するかを選択するユーザー入力 (1 / 0) を待ちます。
2. コードの実装
始める前に、次の 3 つのファイルを作成する必要があります。
test.c — 3 つのMob 実装の全体的なロジックを構築するために使用されます。
game.h — 関数に必要なヘッダー ファイルと宣言を保存するために使用されます。
game.c — 関数の本体を保持します
そうすれば、3 つのチェスのコードを完成させることができます
1. メニューを作成する
void mune()
{
选择1开始游戏,选择0退出游戏,选择其他则提示选择错误并重新输入
printf("********************************\n");
printf("******** 三子棋游戏 *********\n");
printf("********************************\n");
printf("******** 1. 开始游戏 *********\n");
printf("******** 0. 退出游戏 *********\n");
printf("********************************\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
mune();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game(); //游戏主体
break;
case 0:
printf("退出游戏!\n");
break;
default :
printf("选择错误,重新选择!\n");
break;
}
} while (input);
return 0;
}
2. ゲーム本体を実現する
(1) 3*3 チェス盤を定義し、チェス盤を初期化して出力します - 空席を表すためにスペースを使用します
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < ROW; i++)
{
int j = 0;
for (j = 0; j < COL; j++)
{
board[i][j] = ' ';
}
}
}
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
//打印数据
printf(" %c ", board[i][j]);
//打印分割线 '|'
if (j != col - 1)
printf("|");
}
printf("\n");
//打印分割线
if (i != row - 1)
{
j = 0;
for (j = 0; j < col; j++)
{
printf("___");
if (j != col - 1)
printf("|");
}
printf("\n");
}
}
printf("\n");
}
印刷結果は以下の通りです
(2) プレイヤーに最初のチップをプレイさせます
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
printf("玩家下棋>:\n");
int x = 0, y = 0;
while (1)
{
printf("请输入下棋的坐标,中间使用空格>:");
scanf("%d %d", &x, &y);
if (x >= 1 & x <= row && y >= 1 && y <= col) //判断是否可以落子
{
if (board[x-1][y-1] = ' ') //可以落子
{
board[x-1][y-1] = '*';
break;
}
else //不能落子
{
printf("坐标被占有,不能落子,重新输入坐标\n");
}
}
else //没有此坐标
{
printf("坐标非法,重新输入\n");
}
}
}
(3) コンピュータはランダムにチェスをプレイします
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0; //0~row-1
int y = 0; //0~col-1
printf("电脑下棋:>\n");
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
コンピューター チェスには sran((unsigned int)time(NULL) 関数と rand() 関数が必要です。これら 2 つの関数を使用するには、ヘッダー ファイル #include<stdlib.h> と #include<time.h> もインクルードする必要があります。 rand によって生成された座標をよりランダムにするには、メイン関数で srand() 関数を使用します。
(4) 勝敗の判定
チェスをプレイした後は、当然、どちらが勝ったかを判断する必要があります。
スリーモブチェスの勝ちサインは、1行か1列、または対角線がすべてプレイヤーかコンピュータの駒であるかどうかであり、勝ちがない場合はチェス盤が引き分けか継続かを判断する必要があります。ゲーム。
//判断输赢
//玩家赢 - '*'
//电脑赢 - '#'
//平局 - 'Q'
//继续 - 'C'
char IsWin(char board[ROW][COL], int row, int col)
{
int i = 0, j = 0;
//行
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
{
return board[i][0];
}
}
//列
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] && board[2][j] && board[0][j] != ' ')
{
return board[0][j];
}
}
//对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
//平局
if (IsFull(board, row, col) == 1)
{
return 'Q';
}
//继续
return 'C';
}
int IsFull(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
3. 最終コードの実装
ゲームの内容.h
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 3
#define COL 3
//游戏函数声明
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);
//判断输赢
//玩家赢 - '*'
//电脑赢 - '#'
//平局 - 'Q'
//继续 - 'C'
char IsWin(char board[ROW][COL], int row, int col);
game.c のコンテンツ
#include "game.h"
//游戏函数的实现
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < ROW; i++)
{
int j = 0;
for (j = 0; j < COL; j++)
{
board[i][j] = ' ';
}
}
}
//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
//打印数据
printf(" %c ", board[i][j]);
//打印分割线 '|'
if (j != col - 1)
printf("|");
}
printf("\n");
//打印分割线
if (i != row - 1)
{
j = 0;
for (j = 0; j < col; j++)
{
printf("___");
if (j != col - 1)
printf("|");
}
printf("\n");
}
}
printf("\n");
}
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
printf("玩家下棋>:\n");
int x = 0, y = 0;
while (1)
{
printf("请输入下棋的坐标,中间使用空格>:");
scanf("%d %d", &x, &y);
if (x >= 1 & x <= row && y >= 1 && y <= col) //判断是否可以落子
{
if (board[x-1][y-1] = ' ') //可以落子
{
board[x-1][y-1] = '*';
break;
}
else //不能落子
{
printf("坐标被占有,不能落子,重新输入坐标\n");
}
}
else //没有此坐标
{
printf("坐标非法,重新输入\n");
}
}
}
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
int x = 0; //0~row-1
int y = 0; //0~col-1
printf("电脑下棋:>\n");
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
//判断输赢
//玩家赢 - '*'
//电脑赢 - '#'
//平局 - 'Q'
//继续 - 'C'
char IsWin(char board[ROW][COL], int row, int col)
{
int i = 0, j = 0;
//行
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
{
return board[i][0];
}
}
//列
for (j = 0; j < col; j++)
{
if (board[0][j] == board[1][j] && board[1][j] && board[2][j] && board[0][j] != ' ')
{
return board[0][j];
}
}
//对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
//平局
if (IsFull(board, row, col) == 1)
{
return 'Q';
}
//继续
return 'C';
}
int IsFull(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
return 0;
}
}
}
return 1;
}
test.c の内容
#include "game.h"
void mune()
{
选择1开始游戏,选择0退出游戏,选择其他则提示选择错误并重新输入
printf("********************************\n");
printf("******** 三子棋游戏 *********\n");
printf("********************************\n");
printf("******** 1. 开始游戏 *********\n");
printf("******** 0. 退出游戏 *********\n");
printf("********************************\n");
}
void game()
{
int ret = 0;
char board[ROW][COL] = {
0 };
//初始化棋盘
InitBoard(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
break;
//电脑下棋
ComputerMove(board, ROW, COL);
//打印棋盘
DisplayBoard(board, ROW, COL);
//判断输赢
ret = IsWin(board, ROW, COL);
if (ret != 'C')
break;
}
//判断 玩家/电脑 输赢或平局
if (ret == '*')
printf("玩家赢\n");
else if (ret == '#')
printf("电脑赢\n");
else
printf("平局\n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
mune();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game(); //游戏主体
break;
case 0:
printf("退出游戏!\n");
break;
default :
printf("选择错误,重新选择!\n");
break;
}
} while (input);
return 0;
}
最終的な実現
3. まとめ
バックギャモンの実装コードには細かい部分が多く、細部に注意が必要な箇所が多くあります。特に注意が必要な部分は、チェス盤を印刷する際の境界線の調整方法とメニュー構造のデザインです。コード内の重複をできるだけ避けるために、個々の関数の実装について知る必要があります。