目錄
前言
本文適合有一定c語言基礎的小伙伴,基礎稍微薄弱的可能看著會有點吃力,但并不會影響對思路的把握,這型別的程式要求有一些基礎,它可以體現你對所學知識的整體掌握程度 在閱讀本文前,希望你們已經掌握了以下知識包括 頭檔案 源檔案定義及作用 函式及函式傳參函式傳參 回圈 陣列(二維陣列)
正文
引入
代碼程式化
2.棋盤 Board()
3.下棋 Move()
4.判斷規則或者叫游戲規則 Judge()
后話
前言
本文適合有一定c語言基礎的小伙伴,基礎稍微薄弱的可能看著會有點吃力,但并不會影響對思路的把握,這型別的程式要求有一些基礎,它可以體現你對所學知識的整體掌握程度 在閱讀本文前,希望你們已經掌握了以下知識
包括 頭檔案 源檔案定義及作用 函式及函式傳參函式傳參 回圈 陣列(二維陣列)
本文將展示寫程式的思路,以及代碼實作
正文
引入
三子棋應該具有哪些要素?或者說你想設計一個小游戲,你希望它有什么功能呢?
以三子棋為例,我覺得應該有以下的功能
1.選單
2.棋盤
3.玩家和電腦下棋
4.判斷規則
ok,功能已經想好了,那就開始把它們用程式寫出來
代碼程式化
1.選單 menu()
代碼如下:
void menu()
{
printf("************三子棋游戲************\n");
printf("****** 1. play *** 0. exit ******\n");
printf("*********************************\n");
}選單可以自己設計,你覺得好看就行
2.棋盤 Board()
你覺得棋盤有該有哪些功能?
我覺得應該有初始化功能 InitializeBoard() 和 顯示功能DisplayBoard()
于是我們有了以下代碼
//用陣列來存放我們要下的棋子 char Board[ROW][COL] = { 0 };//棋盤初始化 陣列里面的元素為空格,視覺上看起來棋盤是空的 void InitializeBoard(char Board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { 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++)//列印第i行的內容 { //列印資料行 printf(" %c ", Board[i][j]);//對應下圖的1號綠色圓角方框 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"); } } }看到這里可能有小伙伴會對DisplayBoard()的寫法有點疑問,希望下面的這張圖能打消你的疑慮

左邊紅色的橢圓代表Board[i][j],右邊的1號綠色圓角方框代表" Board[i][j] "對應代碼的 " %c "(注意中間空白是一個空格哦) 2號方框代表豎著的分割線 對應代碼中的 "|" ,那么3號方框代表什么應該知道了吧,沒錯,就是代碼中的"---"
為什么要這么設定呢?那是因為這才是列印出棋盤的最小"回圈單元"這里就不細述原因了,畢竟這不是代碼的重點.如果有疑惑的話可以私信我哦
3.下棋 Move()
有兩個玩家(玩家和電腦)那就自然有兩個函式啦
玩家下棋PlayerMove() 和 電腦下棋ComputerMove()
因為我們在上面已經將棋盤的元素初始化為空格了所以要想下棋的話 就把棋盤上對應坐標的空格替換成代表玩家棋子的字符 "*" "#"就行啦,這里呢我們用"*"代表玩家的棋子,"#"代表電腦的棋子,當然你想用什么表示就用什么表示,只要是個字符就可以了.
void PlayerMove(char Board[ROW][COL], int row, int col)
{
//用坐標來表示位置
int x = 0;
int y = 0;
printf("玩家走\n");
while (1)//考慮到玩家有可能會不小心輸入錯誤坐標,so 應該設計while回圈
{
printf("請輸入要下的坐標: ");
scanf_s("%d%d", &x, &y);
//判斷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)
{
//利用rand函式不斷產生亂數
x = rand() % row;
y = rand() % col;
if (Board[x][y] == ' ')//電腦他知道陣列定義啊,so 這里直接沒有減一
{
Board[x][y] = '#';
break;
}
}
}
4.判斷規則或者叫游戲規則 Judge()
三子棋三子棋,顧名思義就是三個子的棋(你小子擱著擱著呢!) 開個玩笑
判斷輸贏規則無非就是四條 三行三列兩對角,只要這四條線上的棋子一致就贏了
當然還應該有個函式IsFull()共同來判斷當前游戲狀態 是平局呢,是玩家贏呢,是電腦贏呢,還是該繼續游戲呢
代碼如下
int IsFull(char Board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (Board[i][j] == ' ')
{
return 0;//沒滿
}
}
}
return 1;//滿了
}
char Judge(char Board[ROW][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][1] != ' ')
{
return Board[i][1];
}
}
//豎三列
for (i = 0; i < col; i++)
{
if (Board[0][i] == Board[1][i] && Board[1][i] == Board[2][i] && Board[1][i] != ' ')
{
return Board[1][i];
}
}
//兩個對角線
if (Board[0][0] == Board[1][1] && Board[1][1] == Board[2][2] && Board[1][1] != ' ')
return Board[1][1];
if (Board[2][0] == Board[1][1] && Board[1][1] == Board[0][2] && Board[1][1] != ' ')
return Board[1][1];
//判斷是否平局
if (1 == IsFull(Board, ROW, COL))
{
return "Q";
}
//繼續
return 'C';
}
三行三列的判斷上我覺得我們寫的代碼應該差不多
但是在兩對角線的寫法上有小伙伴會說,既然三行三列都可以用回圈表達,那么兩對角線應該也可以
for (i = 0; i < row; i++)//左上-右下
{
if (Board[i][i] == Board[i + 1][i + 1])
continue;
else
break;
}
for (i = 0; i < row; i++)//左下-右上
{
if (Board[i][row-1-i] == Board[i + 1][row -2-i])//當i=2的時候陣列會越界
continue;
else
break;
}
對,思路沒問題,只是會產生越界的情況,那可不可以避免呢?答案是可以.只要在定義ROW和COL的時候,多加個2,比如,這個程式是三子棋,ROW,COL為3,只要定義它倆為5,讓整個棋盤多一圈,我們在對Board[][]陣列進行操作時只操作其下標中的1-3就行了.這里就只給出思路了,感興趣的小伙伴可以自己嘗試一下,我相信你要是能嘗試下去就可以摸索出n子棋的寫法.
全域代碼如下
有三個板塊,一個頭檔案game.h,兩個源檔案test.c game.c
game.h
//函式宣告部分
#define ROW 3
#define COL 3
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//宣告
void InitializeBoard(char Board[ROW][COL], int row, int col);
void DisplayBoard(char Board[ROW][COL], int row, int col);
void PlayerMove(char Board[ROW][COL], int row, int col);
void ComputerMove(char Board[ROW][COL], int row, int col);
//告訴我們四種游戲的狀態
//玩家贏 - '*'
//電腦贏 - '#'
//平局 - 'Q' 用單字符表示嗷,不要為了顯示你的高英語水平就用字串,越簡潔越好
//繼續 - 'C'
char Judge(char Board[ROW][COL], int row, int col);
game.c
//游戲模塊 函式定義
#include<stdio.h>
#include "game.h"
void InitializeBoard(char Board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
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++)//列印第i行的內容
{
//列印資料行
printf(" %c ", Board[i][j]);//對應下圖的1號綠色圓角方框
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)//考慮到玩家有可能會不小心輸入錯誤坐標,so 應該設計while回圈
{
printf("請輸入要下的坐標: ");
scanf_s("%d%d", &x, &y);
//判斷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)
{
//利用rand函式不斷產生亂數
x = rand() % row;
y = rand() % col;
if (Board[x][y] == ' ')//電腦他知道陣列定義啊,so 這里直接沒有減一
{
Board[x][y] = '#';
break;
}
}
}
//判斷棋盤滿沒滿
//回傳1表示棋盤滿了
//回傳0,表示棋盤沒滿
int IsFull(char Board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (Board[i][j] == ' ')
{
return 0;//沒滿
}
}
}
return 1;//滿了
}
//三行三列兩對角
char Judge(char Board[ROW][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][1] != ' ')
{
return Board[i][1];
}
}
//豎三列
for (i = 0; i < col; i++)
{
if (Board[0][i] == Board[1][i] && Board[1][i] == Board[2][i] && Board[1][i] != ' ')
{
return Board[1][i];
}
}
//兩個對角線
if (Board[0][0] == Board[1][1] && Board[1][1] == Board[2][2] && Board[1][1] != ' ')
return Board[1][1];
if (Board[2][0] == Board[1][1] && Board[1][1] == Board[0][2] && Board[1][1] != ' ')
return Board[1][1];
//判斷是否平局
if (1 == IsFull(Board, ROW, COL))
{
return "Q";
}
//繼續
return 'C';
}
test.c
//來測驗我們的三子棋程式 測驗模塊
#include "game.h"
void menu()
{
printf("************三子棋游戲***********\n");
printf("****** 1. play *** 0. exit ******\n");
printf("*********************************\n");
}
void game()
{
//存放Judge()函式的回傳值
char ret = 0;
//用陣列來存放我們要下的棋子
char Board[ROW][COL] = { 0 };
//棋盤初始化 陣列里面的元素為空格,視覺上看起來棋盤是空的
InitializeBoard(Board,ROW,COL);//因為要使用這個初始化函式,就得宣告,而初始化函式是game函式的一部分,所以我們應該在 game.h 這個頭檔案中對其進行宣告
//列印棋盤
DisplayBoard(Board, ROW, COL);
//下棋,也就是"填空",把已經初始化的棋盤上的 ' ' 替換成玩家和電腦要走的棋子
while (1)
{
//玩家走
PlayerMove(Board, ROW, COL);
DisplayBoard(Board, ROW, COL);
ret=Judge(Board, ROW, COL);
//判斷玩家是否贏
if (ret != 'C')
{
break;
}
//電腦走
ComputerMove(Board,ROW,COL);
DisplayBoard(Board, ROW, COL);
//判斷電腦是否贏
ret = Judge(Board, ROW, COL);
if (ret != 'C')
{
break;
}
}
//判斷剩下三種情況
if (ret == '*')
{
printf("玩家贏\n");
}
else if (ret == '#')
{
printf("電腦贏\n");
}
else
{
printf("平局\n");
}
}
void test()
{
int choice;
srand((unsigned int)time(NULL));//時間戳,配合rand函式
do
{
menu();
printf("請選擇:\n");
scanf_s("%d", &choice);
switch (choice)
{
case 1:
printf("開始游戲\n");//system clc
game();
break;
case 0:
printf("退出游戲");
break;
default:
printf("輸入無效,請重新輸入\n");
}
} while (choice);
}
int main()
{
test();
return 0;
}
這個是三個檔案創建好后的亞子

最后附上我和電腦之間的"博弈"

后話
可能有人會說要是可以滑鼠點擊就好了,點哪里就落子哪里,畢竟這是一個小程式,而不是一個正
真意義上的游戲,而且編者水平有限,才剛開始學,實作起來有點困難,今天埋下一個伏筆,等我
學得差不多了,我就來補上
如果有想交流的可以評論或者私信
最后希望各位小伙伴在做類似的綜合性比較高的題時可以畫思維導圖,好處 思路清晰,不會去想
一步寫一步,時刻告訴自己這一步該做什么,我要實作什么功能
全文一共八千八百多個字,看了這么久螢屏要注意保護眼睛哦
回見!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/300822.html
標籤:其他
上一篇:行程 執行緒 協程(Unity)
下一篇:Unity 異步
