バックギャモン
序文
C 言語での 3 行の実装は、みんなの配列、関数、ループ、分岐の調査です。この記事では、スリームーン ゲームの作り方を学びます。しばらく復習すれば、スリームーン ゲームをマスターできるようになると思います** (スリームーン ゲームの完全なコードは、次のリンクに添付されています)記事の最後)。**
1. ゲームのルール
ゲームを設計する前にバックギャモンの基本ルールを理解し、そのルールに基づいて C 言語で実装します。
1. 人間と機械の両方が交代でチェスの駒をグリッドに配置し、最初に 3 つのチェスの駒の列を形成した人が勝利とみなされます。
2. チェス盤がチェスの駒でいっぱいで、それでも勝者がいない場合は、引き分けとみなされます。
2つ目は必要書類
Three chess は簡単なコードではないため、別のファイルを記述する必要があります。
サブファイル書き込みとは何ですか?
それは、プログラムコードを複数のファイルに分割し、すべてのコードを main.c に入れるのではなく、サブモジュールというプログラミングの考え方を採用し、機能を分割し、異なる機能を持つ各機能を 1 つの C に入れることです。ファイルを作成し、それを呼び出し可能な関数にカプセル化するヘッダー ファイルを作成し、このカプセル化された関数を main 関数で呼び出し、コンパイル時に一緒にコンパイルします。
利点:
a. 機能責任の分割
b. 便利なデバッグ
c. 簡潔なメインプログラム
以下に具体的な操作を示します。
ヘッダファイルに game.h を作成 ---- 関数の宣言に使用
ソースファイルに game.c を作成 - 関数実装 / test.c - テーマ処理
第三に、メニューを作成します
まず、ゲームの開始と終了の機能を表示するメニューを作成します。
void menu()
{
printf("**********************\n");
printf("****** 1.play ******\n");
printf("****** 0.exit ******\n");
printf("**********************\n");
}
do...while ループを使用してメニューの使用を実現し、switch ステートメントを使用してメニューを選択します
int main()
{
int input = 0;
do
{
menu();
printf("请输入选项>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏>\n");
break;
default:
printf("选择错误,重新选择>\n");
break;
}
} while (input);
return 0;
}
第四に、ゲームの核心コンテンツの実現
ゲーム全体を game() 関数で実装し、最初にボードを配列します
char board[ROW][COL];
1. ボードの初期化
game.h で行と列を 3 として定義します。
#define ROW 3
#define COL 3
game.hで初期化関数Initboardを宣言します。
//初始化棋盘
void Initboard(char board[ROW][COL], int row, int col);
game.c に初期化関数を実装して、3 行 3 列のスペースを作成します。
void Initboard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
初期化が完了するまでお待ちください。
1. チェス盤の表示
チェス盤を初期化した後、キーボードでチェス盤を印刷する必要があります
。game.file でチェス盤を宣言して印刷します。
//打印棋盘
void Displayboard(char board[ROW][COL], int row, int col);
game.c ファイルにチェッカーボード印刷機能を実装します。
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
//先打印数据
printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
//再打印分割行
if(i<row-1)
printf("---|---|---\n");
}
}
チェス盤がプリントされています
3. プレイヤーはチェスをプレイします
game.h でプレーヤーのチェス関数を宣言します。
//玩家下棋
void Playermove(char board[ROW][COL], int row, int col);
プレーヤーのチェス関数を game.h に実装します。プレーヤーがプレイしているチェスの駒はボードの外に出ることはできません。そうしないと、その座標は再プレイできません。チェスの駒は、チェス駒のないグリッド内になければなりません。そうでない場合は、座標が占有されて再プレイされます。
void PlayerMove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家下棋\n");
while (1)
{
printf("请输入要下棋的坐标:>");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x-1][y-1] == ' ')//数组下标从0开始所以横纵坐标各减一
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("该坐标被占有,请输入其他坐标\n");
}
}
else
{
printf("坐标非法,请重新输入\n");
}
}
}
プレイヤーはチェスのプレイを終了しました。
4. コンピューターチェス
game.h でコンピューターのチェス関数を宣言します。
//电脑下棋
void Computermove(char board[ROW][COL], int row, int col);
game.c ファイルでコンピュータ チェスの機能を実現します。ランダム座標ヘッダー ファイル #include <stdlib.h> はコンピューターがチェスをランダムにプレイするために必要であり、ヘッダー ファイル #include <time.h> は乱数の生成に必要です。コンピュータがチェス盤上でプレイするチェスを制御し、そのチェスが空のチェス盤上でプレイされるか再プレイされるかを判断します。一方、プレイヤーが間違ったチェスの駒をプレイしたことに気づき、正しくプレイして終了するまでチェスを再プレイします。ループ
void Computermove(char board[ROW][COL], int row, int col)
{
printf("电脑开始下棋>\n");
int x = 0;
int y = 0;
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
5. 試合結果の判定
game.hで勝敗判定関数を宣言します。
//判断输赢
>char IsWin(char board[ROW], int row, int col);
game.cの勝敗判定機能を実現します。各チェスのゲームには 4 種類の結果があります: 1. プレーヤーの勝ち 2. コンピュータの勝ち 3. 引き分け 4. ゲームを続行します。for ループは、
行と列の 3 つの点が直線上にあることを認識します。プレーヤーまたはコンピュータ上の 3 点が直線上にあると判断された場合は、「*」または「#」を出力します。
char IsWin(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] == board[i][0] && board[i][2] != ' ')//行连成线
{
return board[i][0];
}
}
for(i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] == board[2][i] && board[0][i] != ' ')//列连成线
{
return board[i][0];
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == board[2][2] && board[0][0] != ' ')//斜方连成线
{
return board[0][0];
}
if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[0][2] == board[2][0] && board[1][1] != ' ')//斜方连成线
{
return board[1][1];
}
if (isFull(board, ROW, COL))
{
return 'Q';
}
return 'C';
}
ネストされた描画関数は game.h にあります。すべての座標が占有されている (座標が空ではない) 場合、draw 関数は true を返し、勝利関数は Qdraw を返します。座標が空いている場合、ドロー関数は false を返し、判定関数で C を返してゲームを続行します。
static isFull(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
6. game() 関数の内部実装
配列 char board[ROW][COL]; を作成し、ボードの初期化関数 (Initboard(board, ROW, COL)) とボードの印刷関数 (Displayboard(board, ROW, COL)) を呼び出し、while ループで次のことを実現します。コンピュータとプレイヤーが互いにチェスをすることは、勝敗の結果を受け入れず、ゲームを続行しない場合にはループから抜け出すことを意味します (C)。結果がプレイヤー (*) の場合はプレイヤーの勝ち、結果がコンピューター (#) の場合はコンピューターの勝ち、それ以外の場合は結果は引き分けです。
void game()
{
int ret = 0;
char board[ROW][COL];
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");
}
}
4番目、実際のゲーム操作
1. プログラムを実行すると、メニューが表示されます。
1. 1 を選択してゲームを開始すると、チェス盤が表示されます。
2. チェスのポジションを入力して、チェスのプレイを開始します。
3. チェスの駒が空のポジションに落ちない場合は、チェスをプレイします。再び
4. 直線上の 3 点が表示され、勝ちます
5 ボードがいっぱいの場合は引き分けになります
6. 0 を選択してゲームを終了します
完全なコード:
ゲーム.h
#pragma once
#include <stdio.h>
#include <time.h>
#include <stdlib.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);
//判断输赢
char IsWin(char board[ROW], int row, int col);
ゲーム.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void Initboard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
void Displayboard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
printf("|");
}
printf("\n");
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
printf("|");
}
}
printf("\n");
}
}
void Playermove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家要下棋:\n");
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)
{
printf("电脑开始下棋>\n");
int x = 0;
int y = 0;
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
static isFull(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
char IsWin(char board[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] == board[i][0] && board[i][2] != ' ')
{
return board[i][0];
}
}
for(i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] == board[2][i] && board[0][i] != ' ')
{
return board[i][0];
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] == board[2][2] && board[0][0] != ' ')
{
return board[0][0];
}
if (board[2][0] == board[1][1] && board[1][1] == board[0][2] && board[0][2] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
if (isFull(board, ROW, COL))
{
return 'Q';
}
return 'C';
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//创建菜单
void menu()
{
printf("**********************\n");
printf("****** 1.play ******\n");
printf("****** 0.exit ******\n");
printf("**********************\n");
}
//创建游戏
void game()
{
int ret = 0;
char board[ROW][COL];
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
{
menu();
printf("请输入选项>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏>\n");
break;
default:
printf("选择错误,重新选择>\n");
break;
}
} while (input);
return 0;
}
このラウンドの 3 月チェスの学習は終了しました。詳細な 3 月チェス + 完全なコードを繰り返し読み、コーディングを続けてください。近い将来、3 月チェスで勝利して、より高度なコードを拡張できると信じています。次回お会いできるのを楽しみにしています!!!