[C言語][ゲーム][スリーコネクト]
I.はじめに
ゲームのルールは、2 人のプレイヤーが 3x3 のボード上でチェスをプレイし、1 人のプレイヤーの 3 つの駒が直線でつながっている限り、そのプレイヤーの勝ちです。チェス盤がいっぱいで勝者がいない場合は引き分けとなります。このブログではバックギャモンのミニゲームを実現する具体的な手順を紹介していきます。
2. モジュール式プログラミング
モジュラー プログラミング: 各モジュールのコードを異なる .c ファイルに配置し、外部呼び出し可能な関数の宣言を .h ファイルに提供します。他の .c ファイルでそのコードを使用する場合は、 #include "XXX.h" だけを必要とします。 「ファイルは大丈夫です。モジュール式プログラミングを使用すると、コードの可読性、保守性、移植性などが大幅に向上します。
ここでは 3 つのファイルを作成しました: game.h ファイルはカスタム関数の宣言の記述に使用され、test_game.c ファイルは定義の記述に使用され、test.c ファイルはプログラム全体の実装の記述に使用されます。
(ここでは、次のように#include "game.h" を c ファイルに追加してヘッダー ファイルとソース ファイルを接続するだけです) 。
3. ゲームのアイデア
1. ゲームの開始と終了を選択するメニュー機能を作成します。
2. まず、チェス盤を初期化します。(ゲームはゲーム中にデータを保存する必要があります。3*3 の 2 次元配列 char ボード[3][3] を使用できます。) 3. 次に、ボードを印刷します
。
4. プレイヤーはチェスをプレイします。(プレイヤーは手を打つ位置に入る、'x' = プレイヤーが動く)
5. コンピューターはチェスをプレイするために手を打つ。(配置位置はランダム、「o」= コンピュータ配置)
6. 結果の判断方法! プレイヤーの勝ち、コンピュータの勝ち、引き分けです。完了していない場合は続行します。(プレイヤーが勝って文字「x」を返し、コンピュータが勝って文字「o」を返し、同点の場合は文字「p」を返し、引き続き文字「c」を返します)
4. ゲームの手順/プロセスを理解する
1. ゲームの開始とゲームの終了を選択するメニュー機能を作成します
1). メニューを作成する
ボイドメニュー()
void menu()
{
printf("*************************\n");
printf("****** 1.开始游戏 *****\n");
printf("****** 0.退出程序 *****\n");
printf("*************************\n");
}
テスト:
2). 「ゲームに入る」と「ゲームを終了」を選択します。
#include "game.h"
void menu()
{
printf("*************************\n");
printf("****** 1.开始游戏 *****\n");
printf("****** 0.退出程序 *****\n");
printf("*************************\n");
}
int main()
{
int x=0;
do
{
menu();
scanf("%d", &x);
if (x == 1) {
game();
break;
}
else if (x == 0)
break;
else
printf("笨蛋,输错了,请重新输入:\n");
} while (1);
printf("退出游戏\n");
}
ここで do while ループが使用されているのは、プレーヤーが最初からゲームを開始するかどうかを判断する必要があり、プレーヤーが間違いを犯した場合はテストに再入力する必要があるためです
。
2. ボードの初期化
void InitBoard(char board[3][3], int row, int col)
{
int i, j;
for(i=0;i<row;i++)
for (j = 0; j < col; j++)//初始化棋盘,数组里都是空格
{
board[i][j] = ' ';
}
}
3. チェス盤を印刷する
プレイヤーに見えるチェス盤は、チェスをプレイできるいくつかの分離線と空の位置 (2 次元配列) で構成されている必要があります。これらの線は、プレイヤーがボードのランクと列を確認するのに便利で、2 次元配列はチェスの駒を格納するために使用されます。分割線は視覚的なチェス盤であり、2 次元配列は実際のチェス盤 (チェスの駒を配置する) であることが理解できるので、ルールを見つけて上から下に 1 行ずつ出力します。
void DisplayBoard(char board[][COL], int row, int col)//打印棋盘
{
int i, j;
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");
}
}
}
テスト:
4. プレイヤーはチェスをプレイします
まずプレーヤーにチェスをプレイするよう促し、行数と列数をスペースを入れて入力し、プレーヤーがチェスをプレイした後にチェス盤を印刷します。以前は、この 2 次元配列の各要素を ' ' として代入していましたが、今回は選択した ' ' をチェスの駒に変更し、上で書いたチェス盤を出力する関数を再度呼び出すだけです。
void PlayerMove(char board[][COL], int row, int col)//玩家下棋
{
int x, y;
printf("玩家下棋:\n");
printf("请输入下棋的坐标,中间使用空格:\n");
while (1)
{
scanf("%d %d", &x, &y);//坐标要合法
if (x >=1 && x <= row && y>=1 && y <= row)
{
if (board[x - 1][y - 1] == ' ')//可以落子
{
board[x - 1][y - 1] = 'X';
break;
}
else
printf("坐标被占用,不能落子\n");
}
else//坐标非法
printf("笨蛋输错了,请重新输入:\n");
}
}
テスト:
5. コンピューターはチェスをする
コンピューターはプレーヤーと同じようにチェスをプレイします。コンピューターはヒントを与えずに直接チェスをプレイします。コンピューターはランダムにチェスをプレイするため、ここでは乱数を使用する必要があります。
void ComputerBorad(char board[][COL], int row, int col)//电脑下棋
{
int x, y;
printf("电脑下棋:\n");
Sleep(1500);//用来表示电脑思考了1.5秒
while (1)
{
x = rand() % row;//电脑下棋对应的行坐标
y = rand() % col;//电脑下棋对应的列坐标
if (board[x][y] == ' ')
{
board[x][y] = 'O';
break;
}
}
}
テスト:
6. 勝敗の判定方法!プレイヤーの勝ち、コンピュータの勝ち、引き分けです。終わっていない場合は続行
1). 勝敗の判定方法!プレイヤーの勝ち、コンピュータの勝ち、引き分けです。(チェスをプレイした後、プレイヤーの勝ち、コンピューターの勝ち、引き分け、続行の合計 4 つの結果があります。関数を作成するときは、これら 4 つの状況に対応して、「*O」、「X」、「P」、「C」を返します。それぞれで、チェスをプレイするたびに判断する必要があります。最初に勝ちか負けかを判断し、ここでは勝ちのあらゆる結果を判断する必要があります。勝てなかった場合は引き分けだけを気にし、続行してください。引き分けがなかったら。)
char IsWin(char board[][COL], int row, int col)//判断输赢
{
int i;
//赢的情况下
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 (i = 0; i < col; i++)//列
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
return board[0][i];
}
//对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
return board[1][1];
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
return board[1][1];
}
同点かどうかを判断する
int IsFull(char board[][COL], int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
5. 総コード量
1. test.c ファイルのコード
#include "game.h"
void menu()
{
printf("*************************\n");
printf("****** 1.开始游戏 *****\n");
printf("****** 0.退出程序 *****\n");
printf("*************************\n");
}
void game()
{
char board[ROW][COL] = {
0 };
char a=0;
InitBoard(board, ROW, COL);//初始化棋盘
DisplayBoard(board, ROW, COL);//打印棋盘
while (1)
{
PlayerMove(board, ROW, COL);//玩家下棋
DisplayBoard(board, ROW, COL);//打印棋盘
a=IsWin(board, ROW, COL);//判断输赢
if (a != 'C')
break;
ComputerBorad(board, ROW, COL);//电脑下棋
DisplayBoard(board, ROW, COL);//打印棋盘
a = IsWin(board, ROW, COL);//判断输赢
if (a != 'C')
break;
}
if (a == 'X')
printf("玩家赢啦\n");
else if (a == 'O')
printf("电脑赢啦\n");
else if(a=='P')
printf("平局\n");
}
int main()
{
srand((unsigned)time(NULL));
int x=0;
do
{
menu();//菜单
scanf("%d", &x);
if (x == 1)
{
game();//游戏
break;
}
else if (x == 0)
break;
else
printf("笨蛋,输错了,请重新输入:\n");
} while (1);
printf("退出游戏\n");
}
2. test_game.c ファイルのコード
#include "game.h"
void InitBoard(char board[3][3], int row, int col)//初始化棋盘
{
int i, j;
for(i=0;i<row;i++)
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
void DisplayBoard(char board[][COL], int row, int col)//打印棋盘
{
int i, j;
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[][COL], int row, int col)//玩家下棋
{
int x, y;
printf("玩家下棋:\n");
printf("请输入下棋的坐标,中间使用空格:\n");
while (1)
{
scanf("%d %d", &x, &y);//坐标要合法
if (x >=1 && x <= row && y>=1 && y <= row)
{
if (board[x - 1][y - 1] == ' ')//可以落子
{
board[x - 1][y - 1] = 'X';
break;
}
else
printf("坐标被占用,不能落子\n");
}
else//坐标非法
printf("笨蛋输错了,请重新输入:\n");
}
}
void ComputerBorad(char board[][COL], int row, int col)//电脑下棋
{
int x, y;
printf("电脑下棋:\n");
Sleep(1500);//1.5秒
while (1)
{
x = rand() % row;//电脑下棋对应的行坐标
y = rand() % col;//电脑下棋对应的列坐标
if (board[x][y] == ' ')
{
board[x][y] = 'O';
break;
}
}
}
char IsWin(char board[][COL], int row, int col)//判断输赢
{
int i;
//赢的情况下
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 (i = 0; i < col; i++)//列
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
return board[0][i];
}
//对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
return board[1][1];
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
return board[1][1];
//平局的情况下
if (IsFull(board, row, col) == 1)
{
return 'P';
}
return 'C';
}
int IsFull(char board[][COL], int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
3. game.h ファイルのコード
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#define ROW 3//棋盘的行数
#define COL 3//棋盘的列数
void InitBoard(char board[3][3], int row, int col);//初始化棋盘
void DisplayBoard(board, row, col);//打印棋盘
void PlayerMove(char board[][COL], int row, int col);//玩家下棋
void ComputerBorad(char board[][COL], int row, int col);//电脑下棋
char IsWin(char board[][COL], int row, int col);//判断输赢
int IsFull(char board[][COL], int row, int col);//平局的情况
テスト:
コンピュータが勝ち、
プレイヤーが勝ち
. これが私が初めてプレイしたミニゲームです。記念にブログを書きます。