目錄
- 三子棋的介紹
- 三子棋的基本流程
- 用戶互動頁面
- 游戲回圈設定(一盤不過癮,可以選擇一直玩)
- 初始化棋盤
- 列印棋盤
- 玩家落子
- 電腦落子
- 判斷游戲勝負
- 游戲實作函式
- 總代碼
- 小編總結
三子棋的介紹
三子棋又叫井字棋,就是我們小時候上課偷偷和同學在下面玩的圈圈叉叉,
規則很簡單:只要將自己的三個棋子走成一條線,則獲勝
三子棋的基本流程
用戶互動頁面
首先我們要創建一個選單欄函式,實作與用戶的互動
//列印選單
void menu()
{
printf("游戲規則:* 代表玩家的棋子; # 代表電腦的棋子\n");
printf("輸入需要落子的行和列即可落子\n");
printf("三個相同的連成一線則獲勝\n");
printf("**************************************\n");
printf("************* 1.play **********\n");
printf("************* 0.exit **********\n");
printf("**************************************\n");
printf("請選擇是否開始游戲(1 開始游戲 0 退出游戲):\n");
}
效果如下

游戲回圈設定(一盤不過癮,可以選擇一直玩)
這里就需要用到我們學過的一個回圈陳述句–do-while回圈,它可以保證至少進行一次游戲
int main()
{
srand((unsigned int)time(NULL));//用作產生亂數
int input;
do
{
menu();//列印用戶互動選單
scanf("%d", &input);
switch (input)
{
case 1:
printf("開始游戲>\n");
playgame();
break;
case 0:
printf("退出\n");
break;
default:
printf("輸入錯誤!請重新輸入:\n");
}
} while (input);
return 0;
}
初始化棋盤
初始化,棋盤的程序中,需要將棋盤的每一個格子都是空格,這里用一個雙重回圈就可以實作
//初始化棋盤
void InitArr(char arr[ROW][COL],int row,int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
arr[i][j] = ' ';
}
}
列印棋盤
整個棋盤是由棋子和格子構成,棋子用 * 和 # 表示;格子我們用 - 和 | 來構建
再通過for回圈陳述句進行排列,一個規矩大方的棋盤就誕生了
//列印棋盤
void PrintArr(char arr[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", arr[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 arr[ROW][COL], int row, int col)
{
int i=0, j=0;
while (1)
{
scanf("%d%d", &i, &j);
if (i < 0 ||j < 0 || i > row || j >col)//判斷輸入是否正確
{
printf("輸入錯誤!請重新輸入:");
continue;
}
if (i <=row &&i > 0 && j <=col && j > 0)//輸入正確,落子為‘ * ’
{
if (JudgeOccupy(arr, i-1, j-1))//判斷棋格是否被占用
{
arr[i-1][j-1] = '*';
break;
}
else
printf("該棋格已被占用!,請重新輸入:");
}
}
}
上面代碼中,為了簡化代碼,用了一個判斷棋格是否被占用的函式JudgeOccupy(),實作如下
//判斷棋格是否被占用
int JudgeOccupy(char arr[ROW][COL], int row, int col)
{
if (arr[row][col] == '*' || arr[row][col] == '#')
return 0;
else
return 1;
}
最后效果如下

電腦落子
電腦落子和玩家落子差不多,只不過是有電腦隨機產生落子的行和列;怎么隨機產生行和列吶,這里我們要用到一個rand 函式,他的作用是產生一個0-32767的亂數,在模上一個3,就可以得到0-3之間的亂數了,
//電腦落子
void ComputerMove(char arr[ROW][COL], int row, int col)
{
while (1)
{
int i = rand() % 3;//產生行和列
int j = rand() % 3;
if (JudgeOccupy(arr, i, j))
{
arr[i][j] = '#';
break;
}
}
}
判斷游戲勝負
在游戲進行的程序中我們會遇見4種情況:
1.玩家贏了
2.電腦贏了
3.棋盤滿了,平局了
4.什么事情都沒發生,游戲繼續,
那么我們規定這個判斷游戲勝負的函式,如果玩家贏了回傳‘ * ’,電腦贏了回傳‘ # ’,平局了回傳‘ Q’,無事發生游戲繼續回傳‘ C ‘,
//判斷是否贏得比賽
char JudgeWin(char arr[ROW][COL], int row, int col)
{
//判斷一行是否相等
for (int i = 0; i < row; i++)
{
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2]&&arr[i][1]!=' ')
return arr[i][1];
}
//判斷一列是否相等
for (int i = 0; i < col; i++)
{
if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' ')
return arr[0][i];
}
//判斷對角線是否相等
if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[0][0] != ' ')
return arr[0][0];
if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[0][2] != ' ')
return arr[0][2];
int ret = IsFull(arr, row, col);
if (ret == 1)
return 'Q';
//什么都沒發生繼續游戲
return 'C';
}
上面代碼中判斷棋盤是否滿了的函式IsFull()實作如下
//判斷棋盤是否滿了
int IsFull(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
return 0;
}
}
return 1;
}
游戲實作函式
這個函式,我們需要將上面的函式整合到一起,實作一個游戲的運行整個程序,
//游戲的實作
void playgame()
{
int ret = 0;
char arr[ROW][COL] = { 0 };
InitArr(arr, ROW, COL);//初始化棋盤
PrintArr(arr, ROW, COL);//列印棋盤
while (1)
{
printf("玩家走>\n");
PlayerMove(arr, ROW, COL);
PrintArr(arr, ROW, COL);
ret = JudgeWin(arr, ROW, COL);//判斷玩家是否獲勝
if (ret != 'C')
break;
printf("電腦走>\n");
ComputerMove(arr, ROW, COL);
PrintArr(arr, ROW, COL);
ret = JudgeWin(arr, ROW, COL);//判斷電腦是否獲勝
if (ret != 'C')
break;
}
if (ret == '*')
printf("恭喜玩家贏了\n");
if (ret == '#')
printf("很遺憾電腦贏了\n");
if (ret == 'Q')
printf("平局\n");
}
效果如下

總代碼
為了方便代碼的管理與測驗,我將全部代碼分為了三部分
1.頭檔案:用于函式的申明
2.game.c檔案:用于函式的實作
3.text.c檔案:代碼的測驗
頭檔案如下
#pragma once
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#define ROW 3//行
#define COL 3//列
//列印選單
void menu();
//游戲的實作
void playgame();
//初始化棋盤
void InitArr(char arr[ROW][COL], int row, int col);
//列印棋盤
void PrintArr(char arr[ROW][COL], int row, int col);
//玩家落子
void PlayerMove(char arr[ROW][COL], int row, int col);
//電腦落子
void ComputerMove(char arr[ROW][COL], int row, int col);
//判斷棋格是否被占用
int JudgeOccupy(char arr[ROW][COL], int row, int col);
//判斷是否贏得比賽
char JudgeWin(char arr[ROW][COL], int row, int col);
//判斷棋盤是否滿了
int IsFull(char arr[ROW][COL], int row, int col);
game.c檔案如下
#include "game.h"
//列印選單
void menu()
{
printf("游戲規則:* 代表玩家的棋子; # 代表電腦的棋子\n");
printf("輸入需要落子的行和列即可落子\n");
printf("三個相同的連成一線則獲勝\n");
printf("**************************************\n");
printf("************* 1.play **********\n");
printf("************* 0.exit **********\n");
printf("**************************************\n");
printf("請選擇是否開始游戲(1 開始游戲 0 退出游戲):\n");
}
//游戲的實作
void playgame()
{
int ret = 0;
char arr[ROW][COL] = { 0 };//創建棋盤
InitArr(arr, ROW, COL);//初始化棋盤
PrintArr(arr, ROW, COL);//列印棋盤
while (1)
{
printf("玩家走>\n");
PlayerMove(arr, ROW, COL);
PrintArr(arr, ROW, COL);
ret = JudgeWin(arr, ROW, COL);//判斷玩家是否獲勝
if (ret != 'C')
break;
printf("電腦走>\n");
ComputerMove(arr, ROW, COL);
PrintArr(arr, ROW, COL);
ret = JudgeWin(arr, ROW, COL);//判斷電腦是否獲勝
if (ret != 'C')
break;
}
if (ret == '*')
printf("恭喜玩家贏了\n");//公布游戲結果
if (ret == '#')
printf("很遺憾電腦贏了\n");
if (ret == 'Q')
printf("平局\n");
}
//初始化棋盤
void InitArr(char arr[ROW][COL],int row,int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
arr[i][j] = ' ';
}
}
//列印棋盤
void PrintArr(char arr[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", arr[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 arr[ROW][COL], int row, int col)
{
int i=0, j=0;
while (1)
{
scanf("%d%d", &i, &j);
if (i < 0 ||j < 0 || i > row || j >col)//判斷是否輸入錯誤
{
printf("輸入錯誤!請重新輸入:");
continue;
}
if (i <=row &&i > 0 && j <=col && j > 0)
{
if (JudgeOccupy(arr, i-1, j-1))//判斷棋格是否被占用
{
arr[i-1][j-1] = '*';//輸入正確,落子為’*‘
break;
}
else
printf("該棋格已被占用!,請重新輸入:");
}
}
}
//電腦落子
void ComputerMove(char arr[ROW][COL], int row, int col)
{
while (1)
{
int i = rand() % 3;
int j = rand() % 3;
if (JudgeOccupy(arr, i, j))
{
arr[i][j] = '#';
break;
}
}
}
//判斷棋格是否被占用
int JudgeOccupy(char arr[ROW][COL], int row, int col)
{
if (arr[row][col] == '*' || arr[row][col] == '#')
return 0;
else
return 1;
}
//判斷是否贏得比賽
char JudgeWin(char arr[ROW][COL], int row, int col)
{
//判斷一行是否相等
for (int i = 0; i < row; i++)
{
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2]&&arr[i][1]!=' ')
return arr[i][1];
}
//判斷一列是否相等
for (int i = 0; i < col; i++)
{
if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[0][i] != ' ')
return arr[0][i];
}
//判斷對角線是否相等
if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[0][0] != ' ')
return arr[0][0];
if (arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[0][2] != ' ')
return arr[0][2];
int ret = IsFull(arr, row, col);
if (ret == 1)
return 'Q';
//什么都沒發生繼續游戲
return 'C';
}
//判斷棋盤是否滿了
int IsFull(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
return 0;
}
}
return 1;
}
text.c檔案
#include "game.h"
int main()
{
srand((unsigned int)time(NULL));
int input;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
printf("開始游戲>\n");
playgame();
break;
case 0:
printf("退出\n");
break;
default:
printf("輸入錯誤!請重新輸入:\n");
}
} while (input);
return 0;
}
小編總結
首先給大家指出以上代碼一個不好的地方,就是棋盤的命名應該為Board,而不是Arr,這樣代碼更具有可讀性,一目了然,(那為啥小編還是寫的Arr,其實我也不想,當我寫完代碼的時候才發現命名有點問題,嗚嗚嗚,全部改回來,太難了,就用的Arr),特在此指出,
如果本文章對你有一點點的幫助,那請點上一個小贊,您的支持與鼓勵,將是我繼續寫作的不竭動力,非常感謝~~
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/280291.html
標籤:其他
上一篇:【C語言基礎學習---三子棋游戲】(包含詳細講解+優化策略及實作)
下一篇:指標的進階(后半)
