相信大家都玩過三子棋吧,在一個九宮格內,誰先實作三個棋子連線,誰就獲得勝利!

今天,我們就一起用C語言來實作簡易版的三子棋,
首先,我們的思路大致如下:
1.程式開始時列印選單,讓玩家選擇開始游戲還是退出游戲
2.玩家選擇游戲后進入游戲
3.判斷輸贏后,重新回到選單
為了更好的管理代碼,我們建立三個檔案,分別是:
game.c 用于游戲函式的實作
game.h 用于游戲函式的宣告
test.c 用于測驗相關的游戲函式
程式主體框架如下:
該框架放在test.c檔案中,用于呼叫游戲函式
enum Choose
{
EXIT,
PLAY
};
int main()
{
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case PLAY:
game();//選擇了玩游戲后,呼叫game函式來進行游戲
break;
case EXIT:
printf("退出游戲\n");
break;
default:
printf("選擇有誤,請重新選擇\n");
break;
}
} while (input);//當input為0時,推出循壞,結束程式
return 0;
}
選單函式的實作:
該函式實作放在game.c檔案中,方便呼叫,方便管理
而該函式的宣告,我們放在game.h中即可,我們只需要在test.c中參考game.h頭檔案就可以使用該函式了
void menu()
{
printf("***************************\n");
printf("******* 1. play *******\n");
printf("******* 0. exit *******\n");
printf("***************************\n");
}
游戲函式的實作:
我們為了日后維護的方便,同時為了能夠將三子棋升級為五子棋甚至更大的棋盤
我們在定義棋盤的時候,不要把大小寫死,可以通過define來定義大小
define定義放在game.h中
#define ROW 3
#define COL 3
接下來就是重中之重的game函式實作
game函式里面,包括了棋盤(二維陣列)創建的函式,棋盤初始化的函式,列印棋盤的函式,玩家下棋的函式,電腦下棋的函式,判斷棋盤是否已滿的函式以及判斷玩家或者電腦是否贏了的函式
由于函式眾多,我們就不一一在game函式內部定義,統一再game函式外定義,通過game函式呼叫來完成游戲程序
void game()
{
//該函式用于實作三子棋
//創建棋盤陣列
char board[ROW][COL];
//初始化棋盤陣列
Initboard(board,ROW,COL);
//列印棋盤
Printboard(board, ROW, COL);
while (1)
{
int ret = 0;
char tmp = 0;
//玩家輸入坐標來下棋
Playermove(board, ROW, COL);
Printboard(board, ROW, COL);
//判斷是否贏了
tmp = Iswin(board, ROW, COL);
if (tmp == '*')
{
printf("玩家贏了\n");
break;
}
else if (tmp == '#')
{
printf("電腦贏了\n");
break;
}
//判斷棋盤是否已滿
ret = Isfull(board, ROW, COL);
if (1 == ret)
break;
//電腦下棋
Computermove(board, ROW, COL);
Printboard(board, ROW, COL);
//判斷是否贏了
tmp = Iswin(board, ROW, COL);
if (tmp == '*')
{
printf("玩家贏了\n");
break;
}
else if (tmp == '#')
{
printf("電腦贏了\n");
break;
}
//判斷棋盤是否已滿
ret = Isfull(board, ROW, COL);
if (1 == ret)
break;
}
}
棋盤初始化的函式:
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 Printboard(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");
for (j = 0; j < col; j++)
{
if (i < row - 1)
printf("--- ");
}
printf("\n");
}
}
玩家下棋的函式:
玩家通過輸入坐標來下棋,同時要注意判斷玩家輸入的坐標是否再棋盤大小范圍之內,還要判斷玩家輸入的坐標對應的位置有沒有放棋子,
void Playermove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("請玩家輸入:>\n");
scanf("%d %d", &x, &y);
//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");
}
}
}
電腦下棋的函式:
電腦下棋,在這里我們就用最簡單的生成亂數來實作,就不設計更優(電腦能夠主動贏,或者會堵玩家棋)的演算法了(其實是我能力有限,想不到QAQ)
void Computermove(char (*board)[COL], int row, int col)
{
printf("電腦走:>\n");
while (1)
{
int x = (rand() % row);
int y = (rand() % col);
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
判斷棋盤是否已滿的函式:
玩家和電腦每走一步,就應該呼叫該函式來判斷棋盤是否已滿,若已滿,則需回傳一個已滿的條件,便于讓回圈終止
int Isfull(char(*board)[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;
}
}
}
if (ROW == i)
{
printf("棋盤已滿,退出游戲\n");
return 1;
}
}
判斷輸贏的函式:
玩家和電腦每走一步,就應該呼叫該函式,用于判斷輸贏,若已經分出勝負,則需要回傳一個能夠判斷輸贏的條件,便于讓回圈終止
char Iswin(char(*board)[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] != ' ')
{
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[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];
}
以上就是各個函式的定義了
我們只需要把思路整理一下,把每一個函式的定義放在game函式之前,并且把以上的函式都放在game.c檔案即可,至于上述函式的宣告,我們放在game.h中,我們只需要再test.c和game.c中各自參考game.h就可以啦
最后的匯總:
test.c
#include"game.h";
//三子棋的測驗
enum Choose
{
EXIT,
PLAY
};
int main()
{
int input = 0;
do
{
menu();
srand((unsigned int)time(NULL));
scanf("%d", &input);
switch (input)
{
case EXIT:
printf("退出游戲\n");
break;
case PLAY:
game();
break;
default:
printf("輸入有誤,請重新選擇\n");
break;
}
} while (input);
return 0;
}
game.c
//游戲相關函式的實作
#include"game.h"
//選單
void menu()
{
printf("************************************\n");
printf("************ 1.play *************\n");
printf("************ 0.exit *************\n");
printf("************************************\n");
}
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 Printboard(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");
for (j = 0; j < col; j++)
{
if (i < row - 1)
printf("--- ");
}
printf("\n");
}
}
void Playermove(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
printf("請玩家輸入:>\n");
scanf("%d %d", &x, &y);
//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");
}
}
}
//char board[ROW][COL]
void Computermove(char (*board)[COL], int row, int col)
{
printf("電腦走:>\n");
while (1)
{
int x = (rand() % row);
int y = (rand() % col);
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
int Isfull(char(*board)[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;
}
}
}
if (ROW == i)
{
printf("棋盤已滿,退出游戲\n");
return 1;
}
}
char Iswin(char(*board)[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] != ' ')
{
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[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];
}
void game()
{
//該函式用于實作三子棋
//創建棋盤陣列
char board[ROW][COL];
//初始化棋盤陣列
Initboard(board,ROW,COL);
//列印棋盤
Printboard(board, ROW, COL);
while (1)
{
int ret = 0;
char tmp = 0;
//玩家輸入坐標來下棋
Playermove(board, ROW, COL);
Printboard(board, ROW, COL);
//判斷是否贏了
tmp = Iswin(board, ROW, COL);
if (tmp == '*')
{
printf("玩家贏了\n");
break;
}
else if (tmp == '#')
{
printf("電腦贏了\n");
break;
}
//判斷棋盤是否已滿
ret = Isfull(board, ROW, COL);
if (1 == ret)
break;
//電腦下棋
Computermove(board, ROW, COL);
Printboard(board, ROW, COL);
//判斷是否贏了
tmp = Iswin(board, ROW, COL);
if (tmp == '*')
{
printf("玩家贏了\n");
break;
}
else if (tmp == '#')
{
printf("電腦贏了\n");
break;
}
//判斷棋盤是否已滿
ret = Isfull(board, ROW, COL);
if (1 == ret)
break;
}
}
game.h
//游戲函式的宣告
//棋盤大小的定義
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3
#define COL 3
void menu();
void game();
好啦,三子棋游戲的實作到這里就結束啦
結語:
創作不易,希望大家可以點贊、評論、轉發、關注一條龍哦!
你們的支持是我創作最大的動力!!
由于本人能力有限,若有錯誤,希望指正!!
如果有更好的方法或者想法,也歡迎再評論區留言哦~

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/302548.html
標籤:其他
上一篇:單片機的最小系統及IO口結構
