C語言實作三子棋
首先我們應該構思:
- 游戲流程
- 每個流程如何代碼實作
游戲流程

我們先構造總體框架,在這里先自定一個menu選單函式,和一個game游戲函式
至于函式主體我們后面再寫
int main()
{
menu();//列印選單
game();//進入游戲
}
開始界面
在這里我們就寫menu函式的主題(一個簡陋的界面,你也可以做任何你想的樣式)
void menu()//列印開始界面
{
printf("**********************************\n");
printf("**** 1.開始游戲 ** 2.結束 *********\n");
printf("**********************************\n");
}
列印完選單后,正式進入game函式
game函式:
- 玩家選擇開始游戲還是結束
- 初始化棋盤
- 讓玩家和電腦依次落子
- 判斷勝負
所以第一步,玩家選擇開始游戲還是結束
這個很簡單,不多贅述
int put;//定義一個整型變數記錄玩家輸入
scanf("%d",&put);
if(put==1)
{
初始化棋盤開始游戲
}
else
{
return 0;
}
第二步,初始化棋盤
首先寫一個BoardPrint函式列印棋盤
我們想列印一個這樣的棋盤
* | * | *
---|---|---
* | * | *
---|---|---
* | * | *
則它可以拆分為
1.
* | * | *
1又可以拆分為兩個(空格)*(空格)|和一個(空格)*(空格)
和2. ---|---|---
2又可以拆分為兩個---|一個---
所以我們有規律的列印一行列印兩個(空格)*(空格)| 一個(空格)*(空格),一行列印兩個---| 一個---
void BoardPrint(char board[ROW][COL], int row, int col)//列印棋盤
{
for (int i = 0; i < row; i++)
{
for (int n = 0;n<col; n++)
{
if (n == col - 1) /如果到了最后一列則不列印字符后的|
{
printf(" %c \n", board[i][n]);
}
else
{
printf(" %c |",board[i][n]);
}
}
if(i<row-1) /最后一行不列印---|---|---
{
for (int j = 0; j < col; j++)
{
if (j == col - 1) /當列印到最后一列時,就不列印 | ,改為列印換行
{
printf("---\n");
}
else
{
printf("---|");
}
}
}
}
}
在這里我們自定一個函式,名為 initBoard
void initBoard(char board[ROW][COL], int row, int col)//初始化棋盤
{
for (int i = 0; i < row; i++)//將二維陣列所有值為空格
{
for (int n = 0; n < col; n++)
{
board[i][n] = ' ';
}
}
}
第三步,讓玩家、電腦依次落子玩家的子為“ * ” ,電腦的子為“ # ”
我們先寫玩家落子代碼,自定一個函式,名為Player_Move
void Player_Move(char board[ROW][COL], int row, int col) /這里的ROW與COL用define定義為3和3
{
int x, y; /定義一個x與y,記錄玩家輸入的坐標
while (1) /寫在回圈內的原因是:如果輸入有誤,則讓玩家重新輸入
{
printf("請輸入你想要落子的坐標:");
scanf_s("%d%d",&x,&y);
if (x > ROW || y > COL) /如果玩家輸入的坐標超過了棋盤大小,則列印超出棋盤
{
printf("超出棋盤");
}
else if (board[x-1][y-1] != ' ') /如果玩家輸入的坐標已經被占用,則列印以下內容
{
printf("該位置被占用");
}
else /如果上述錯誤都沒有,則將玩家輸入的坐標的陣列值變為‘*’(一個星號)
{
board[x - 1][y - 1] = '*'; /
break;
}
}
}
因為玩家所認為的坐標,例如(1,1)在陣列里,應該是(0,0),所以我們記得在改變值的坐標寫為board[x-1][y-1],
接下來寫電腦落子函式,名為Com_Move
void Com_Move(char board[ROW][COL], int row, int col)
{
int x, y;
while (1)
{
x = rand()%row;
y = rand()%col;
if(board[x][y]=' '&& board[x][y]!='*')/如果落子點為空格并且不為*則可以落子
{
board[x][y] = '#';
break;
}
}
}
因為電腦生成的隨機值我們規定了在0~2之間,所以就不用像之前一樣x-1 y-1了,
第四步,判斷勝負
這里我們自定兩個函式,一個名為is_Win用來判斷哪方勝,一個名為is_None用來判斷是否平局
這里勝負怎么判斷呢,我們可以發現有以下幾種情況
豎著三個,橫著三個
主對角線,副對角線各一個
所以代碼如下
char is_Win(char board[ROW][COL], int row, int col)
{
for (int i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2]&& board[i][1]!='0') /行的情況
{
return board[i][1];/回傳三個值中的一個,*或者#
}
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != '0')/列的情況
{
return board[1][i];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != '0')/副對角線的情況
{
return board[1][1];
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != '0')主對角線的情況
{
return board[1][1];
}
if (is_none(board, ROW, COL) == 1)/進入平局函式
{
return 'p';
}
}
}
is_none(char board[ROW][COL], int row, int col)
{
for (int i = 0;i < row; i++)/遍歷陣列,如果遇到一個空格就回傳0,如果一個空格都沒有就跳出for回圈回傳1
{
for (int n = 0; n < col; n++)
{
if (board[i][n] == ' ')
{
return 0;
}
}
}
return 1;
}
綜上,我們整合所有的代碼
#include <stdio.h>
#include "game.h"
#include <stdlib.h>
#include <time.h>
int main()/主函式
{
srand(time(NULL));
menu();
game();
}
void menu()//列印開始界面
{
printf("**********************************\n");
printf("**** 1.開始游戲 ** 2.結束 ********\n");
printf("**********************************\n");
}
void game()
{
char board[ROW][COL] = { 0 };
int put;
scanf_s("%d", &put);
if(put==1)
{
int ret=0;
initBoard(board,ROW,COL);/初始化棋盤
BoardPrint(board, ROW, COL);/列印棋盤
while (1)
{
Player_Move(board, ROW, COL);/玩家落一次子
BoardPrint(board, ROW, COL);/棋盤列印依次
ret = is_Win(board, ROW, COL);/判斷有沒有人贏了
if (ret == '#')
{
printf("電腦贏");
break;
}
else if (ret == '*')
{
printf("玩家贏");
break;
}
else if (ret == 'p')
{
printf("平局");
break;
}
Com_Move(board, ROW, COL);/電腦落一次子
printf("電腦下\n");
BoardPrint(board, ROW, COL);/再列印一次棋盤
ret = is_Win(board, ROW, COL);/再判斷一次有沒有人贏了
if ( ret == '#')
{
printf("電腦贏");
break;
}
else if ( ret == '*')
{
printf("玩家贏");
break;
}
else if (ret == 'p')
{
printf("平局");
break;
}
}
}
else if (put == 2) /如果輸入2就結束游戲
{
return 0;
}
}
void initBoard(char board[ROW][COL], int row, int col)//初始化棋盤
{
for (int i = 0; i < row; i++)
{
for (int n = 0; n < col; n++)
{
board[i][n] = ' ';
}
}
}
void BoardPrint(char board[ROW][COL], int row, int col)//列印棋盤
{
for (int i = 0; i < row; i++)
{
for (int n = 0;n<col; n++)
{
if (n == col - 1)
{
printf(" %c \n", board[i][n]);
}
else
{
printf(" %c |",board[i][n]);
}
}
if(i<row-1)//最后一行不列印---|---|---
{
for (int j = 0; j < col; j++)
{
if (j == col - 1)//當列印到最后一列時,就不列印 | ,改為列印換行
{
printf("---\n");
}
else
{
printf("---|");
}
}
}
}
}
void Player_Move(char board[ROW][COL], int row, int col)
{
int x, y;
while (1)
{
printf("請輸入你想要落子的坐標:");
scanf_s("%d%d",&x,&y);
if (x > ROW || y > COL)
{
printf("超出棋盤");
}
else if (board[x-1][y-1] != ' ')
{
printf("該位置被占用");
}
else
{
board[x - 1][y - 1] = '*';
break;
}
}
}
void Com_Move(char board[ROW][COL], int row, int col)
{
int x, y;
while (1)
{
x = rand()%row;
y = rand()%col;
if(board[x][y]=' '&& board[x][y]!='*')
{
board[x][y] = '#';
break;
}
}
}
char is_Win(char board[ROW][COL], int row, int col)//版本一
{
for (int i = 0; i < row; i++)
{
if (board[i][0] == board[i][1] && board[i][1] == board[i][2]&& board[i][1]!='0')
{
return board[i][1];
}
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != '0')
{
return board[1][i];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != '0')
{
return board[1][1];
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != '0')
{
return board[1][1];
}
if (is_none(board, ROW, COL) == 1)
{
return 'p';
}
}
}
is_none(char board[ROW][COL], int row, int col)
{
for (int i = 0;i < row; i++)
{
for (int n = 0; n < col; n++)
{
if (board[i][n] == ' ')
{
return 0;
}
}
}
return 1;
}
運行結果:
所以你學會了嗎
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/353537.html
標籤:其他
