C語言實作三子棋
- 使用工具
- 基本思路和流程
- 三子棋游戲規則
- 代碼實作思路
- 實作步驟(具體步驟)
- 使用多檔案形式
- 代碼實作
- 選單界面
- 選擇實作
- 初始化和列印棋盤
- 棋盤
- 使用宏定義(重點)
- 初始化棋盤
- 列印棋盤
- 玩家下子
- 玩家下子會遇到的問題
- 電腦下子
- 電腦下子會遇到的問題
- 判斷結果
- 采取回傳值(char 型)
- 整體游戲流程
- 附上所有代碼
- test.c檔案
- game.h檔案
- game.c檔案
使用工具
- Visual Studio 2019
基本思路和流程
三子棋游戲規則
- `在3X3的棋盤里,率先將三個棋子連成一條直線則勝出
代碼實作思路
- 選單界面:選擇開始或者退出游戲
- 初始化棋盤并列印棋盤
- 玩家選擇落子坐標
- 電腦落子
- 每次落子判斷輸贏平還是繼續
- 結束之后選擇繼續游戲還是退出游戲
實作步驟(具體步驟)
使用多檔案形式
- test.c檔案(源檔案):
寫整個游戲的大致程序 - game.h檔案:
參考所需的頭檔案,以及對各個函式的宣告 - game.c檔案(源檔案):
定義在game.h中宣告的函式,實作各個模塊的功能
(源檔案上方只需加上#include “game.h” 即可)
代碼實作
選單界面
- 代碼:
void meau()
{
printf("***********************************\n");
printf("********* 1 . play **********\n");
printf("********* 0 . exit **********\n");
printf("***********************************\n");
}
- 實作后效果:
-
選擇實作
- 玩家可3通過選擇(0/1)來選擇退出或進行游戲
- 代碼:
int main()
{
int input = 0;
srand((unsigned)time(NULL));
do
{
meau();
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的二維陣列,元素型別為char
- 將陣列初始化為 ‘ ’
char board[ROW][COL];
使用宏定義(重點)
- 提高代碼可讀性
- 若以后想要修改棋盤大小,可直接修改
#define ROW 3
#define COL 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)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j != col - 1)
printf("|");
}
}
printf("\n");
}
}
- 實作后效果

玩家下子
玩家下子會遇到的問題
- 人的思維中,坐標是從1開始的,而陣列中的坐標是從0開始的,因此我們需要將玩家輸入的坐標進行-1處理
- 落子范圍(不能超出坐標的范圍)
- 選擇的坐標是否已被占用
從2,3兩點可以得出,我們需要用到一個回圈來解決這兩個問題,當這兩個問題不存在時,便跳出回圈
- 代碼實作:
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)
{
int x = 0;
int y = 0;
printf("電腦走\n");
//隨機生成坐標
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
判斷結果
采取回傳值(char 型)
- 玩家贏——‘*’
- 電腦贏——‘#’
- 平局——‘Q’
- 游戲繼續——‘c’
- 代碼實作:
char Iswin(char board[ROW][COL], int row, int col)
{
//1.判斷輸贏
if (board[0][0] == '*' && board[0][1] == '*' && board[0][2] == '*')
return '*';
else if (board[0][0] == '#' && board[0][1] == '#' && board[0][2] == '#')
return '#';
else if (board[1][0] == '*' && board[1][1] == '*' && board[1][2] == '*')
return '*';
else if (board[1][0] == '#' && board[1][1] == '#' && board[1][2] == '#')
return '#';
else if (board[2][0] == '*' && board[2][1] == '*' && board[2][2] == '*')
return '*';
else if (board[2][0] == '#' && board[2][1] == '#' && board[2][2] == '#')
return '#';
else if (board[0][0] == '*' && board[1][1] == '*' && board[2][2] == '*')
return '*';
else if (board[0][0] == '#' && board[1][1] == '#' && board[2][2] == '#')
return '#';
//2.判斷平局
int flag = 0;
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
flag = 1;
break;
}
}
}
if (flag == 0)
return 'Q';
//3.游戲繼續
return 'c';
}
整體游戲流程
- 代碼:
void game()
{
char board[ROW][COL];//棋盤陣列
//初始化棋盤
InitBoard(board, ROW, COL);
//列印棋盤
DisplayBoard(board, ROW, COL);
//下棋
char ret = 0;
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);//列印棋盤
if (ret != 'c')
break;
}
if (ret == '*')
printf("玩家贏\n");
else if (ret == "#")
printf("電腦贏\n");
else
printf("平局\n");
//DisplayBoard(board, ROW, COL);//列印棋盤
}
附上所有代碼
test.c檔案
#include "game.h"
void meau()
{
printf("***********************************\n");
printf("********* 1 . play **********\n");
printf("********* 0 . exit **********\n");
printf("***********************************\n");
}
void game()
{
char board[ROW][COL];//棋盤陣列
//初始化棋盤
InitBoard(board, ROW, COL);
//列印棋盤
DisplayBoard(board, ROW, COL);
//下棋
char ret = 0;
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);//列印棋盤
if (ret != 'c')
break;
}
if (ret == '*')
printf("玩家贏\n");
else if (ret == "#")
printf("電腦贏\n");
else
printf("平局\n");
//DisplayBoard(board, ROW, COL);//列印棋盤
}
int main()
{
int input = 0;
srand((unsigned)time(NULL));
do
{
meau();
printf("請選擇:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戲\n");
break;
default:
printf("選擇錯誤\n");
break;
}
} while (input);
return 0;
}
game.h檔案
#pragma once
#include <stdio.h>
#include <stdlib.h>
#define ROW 3
#define COL 3
//初始化棋盤
extern void InitBoard(char board[ROW][COL], int row, int col);
//列印棋盤
extern void DisplayBoard(char board[ROW][COL], int row, int col);
//玩家下棋
extern void PlayerMove(char board[ROW][COL], int row, int col);
//電腦下棋
extern void ComputerMove(char board[ROW][COL], int row, int col);
//判斷輸贏
//要回傳四種不同的狀態
//玩家贏 ——'*'
//電腦贏 ——'#'
//平局 ——'Q'
//繼續 ——'c'
extern 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)
{
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)
{
int x = 0;
int y = 0;
printf("電腦走\n");
//隨機生成坐標
while (1)
{
x = rand() % row;
y = rand() % col;
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
char Iswin(char board[ROW][COL], int row, int col)
{
//1.判斷輸贏
if (board[0][0] == '*' && board[0][1] == '*' && board[0][2] == '*')
return '*';
else if (board[0][0] == '#' && board[0][1] == '#' && board[0][2] == '#')
return '#';
else if (board[1][0] == '*' && board[1][1] == '*' && board[1][2] == '*')
return '*';
else if (board[1][0] == '#' && board[1][1] == '#' && board[1][2] == '#')
return '#';
else if (board[2][0] == '*' && board[2][1] == '*' && board[2][2] == '*')
return '*';
else if (board[2][0] == '#' && board[2][1] == '#' && board[2][2] == '#')
return '#';
else if (board[0][0] == '*' && board[1][1] == '*' && board[2][2] == '*')
return '*';
else if (board[0][0] == '#' && board[1][1] == '#' && board[2][2] == '#')
return '#';
//2.判斷平局
int flag = 0;
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
{
flag = 1;
break;
}
}
}
if (flag == 0)
return 'Q';
//3.游戲繼續
return 'c';
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/294059.html
標籤:其他
下一篇:俄羅斯方塊(C語言實作)
