目錄
1.游戲邏輯
1.1 游戲運行邏輯
1.2 代碼的實作邏輯
1.2.1 代碼分模塊
1.2.2 列印選單供用戶選則
1.2.3 操作游戲函式
2.所用到的知識點
1.二維陣列
2.回圈的嵌套
3.亂數的生成
4.#define定義的符號
5.函式的定義與呼叫
6.選擇與回圈
1.1游戲的運行邏輯
三子棋:規則運行規則很簡單,就像平常玩的(井字棋)的規則不能說完全一樣,簡直就是一模一樣,只要是棋盤上的三個棋子連成一列就算獲勝,不管是橫列,數列抑或斜列只要是連成一列就算獲勝,
1.2 代碼實行的邏輯
1.2.1 代碼分模塊
首先,為什么要代碼分模塊呢?
從初學者的角度來說,這個雖說是個小游戲,但是總代碼量也超出了200行,從實
際的角度講,分模塊寫不僅可以講各個函式獨立化是主函式的代碼量變少,對于初學者
來講更有條理清晰之功效,簡直是小白程式員必備技能
如何分模塊呢?
首先,創建三個檔案,一個測驗的源檔案,一個游戲的源檔案,一個游戲的頭檔案
測驗的源檔案專門用來存放測驗所需要用的代碼(廢話文學我算是把玩明白了),游戲
的源檔案來存放實作游戲邏輯的代碼,而游戲的頭檔案用來放各種頭檔案,和各種函式
宣告,
1.2.2 列印選單供用戶選擇(老選單人了)
//這是測驗源檔案的代碼
#include <stdio.h>
void menu()
{
printf("***********************\n");
printf("**1.play*******0.exit**\n");
printf("***********************\n")//讓用戶輸入數字選擇
}
void test()
{
int input=0;
menu();//呼叫個menu函式這里就是列印出來的選單
scanf("%d",&input);
do
{
switch(input)
{
case 1:
{
break;
}
case 2:
{
printf("游戲退出\n");
}
default:
{
printf("請重新輸入");
}
}while(input);
}
}
int main()
{
test();//在主函式里只呼叫個test函式剩下的由test函式來完成
}
1.2.3 操作游戲函式
游戲的測驗檔案部分
1.三子棋本質上就是在操作一個二維陣列在不同位置上放置棋子,為了拓展性夠高我們在表示行和列統一定義兩個符號(也就是常量)
那么常量怎么定義呢?
在游戲的頭檔案里面定義 ,我們現在要用ROW,COL.就要包含這個頭檔案
2.將所有陣列初始化為空格方便我們后期在空格里存放棋子(先在頭檔案中宣告,再在game的源檔案中定義),
3棋盤列印好,就可以下棋了,先玩家下然后電腦下棋下完一次列印一次棋盤方便看見棋下在哪里
4判斷輸贏
//這是測驗源檔案的代碼
#include "game.h"//在呼叫自己的頭檔案的時候用""
void menu()
{
printf("***********************\n");
printf("**1.play*******0.exit**\n");
printf("***********************\n");//讓用戶輸入數字選擇
}
void game()
{
char board[ROW][COL] = { 0 };//操作這個二維陣列用于放置棋子
InitBoard(board, ROW, COL);//初始化這個二維陣列,移步在下面的游戲函式看
Display_Board(board, ROW, COL);//將棋盤現實出來或者列印出來
char ret = is_win(board, ROW, COL);
while (1)//回圈直到判斷出輸贏跳出
{
Player_move(board,ROW,COL);//玩家下棋
Display_Board(board,ROW,COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')//這個判斷條件在棋盤每列印一次之后就判斷一次,直到條件成立
{
break;
}
Computer_move(board,ROW,COL);//電腦下棋
Display_Board(board,ROW,COL);
ret = is_win(board, ROW, COL);
if (ret != 'C')
{
break;
}
}
if (ret == '*')
{
printf("玩家贏\n");
}
if (ret == '#')
{
printf("電腦贏\n");
}
if (ret == 'Q')
{
printf("平局\n");
}
}
void test()
{
int input = 0;
do
{
menu();//呼叫個menu函式這里就是列印出來的選單
scanf("%d", &input);
switch (input)
{
case 1:
{
game();//創建一個游戲函式我們來開始進入游戲了Let`s go
break;
}
case 2:
{
printf("游戲退出\n");
}
default:
{
printf("請重新輸入");
}
}
}while (input);
}
int main()
{
srand((unsigned int)time(NULL));
test();//在主函式里只呼叫個test函式剩下的由test函式來完成
}
游戲的頭檔案
我們可以將所有的頭檔案都放在我們創建的頭檔案最后直接統一呼叫這個頭檔案
//這是三子棋游戲的頭檔案
#include <stdio.h>
#define ROW 3
#define COL 3
#include <stdlib.h>
#include <time.h>
void InitBoard(char board[ROW][COL],int row,int col);//先將這個函式宣告否則會有警告
void Display_Board(char board[ROW][COL],int row,int col);
void Player_move(char board[ROW][COL],int row,int col);
void Computer_move(char board[ROW][COL],int row,int col);
char is_win(char board[ROW][COL],int row,int col);
游戲的源檔案
初識化二維陣列
列印棋盤

3.列印棋盤
首先要考慮在一個普通人看見這個棋盤的時候會樣輸入下標,在輸入的時候就按照普通人的角度輸入,我們再將輸入的內容轉換為真正二維陣列的下標,其實輸入的值跟最后執行的值是不一樣的,
而對于計算機來說就沒有那么多限制,只需要將亂數的范圍限制在陣列小標限定的范圍內即可
亂數:rand()函式,需要呼叫srand()函式,srand()函式的引數也是一個無符號整型的亂數,而這個亂數從哪來呢,這就要引入時間戳的概念了,時間戳:就是現在時間與第一臺計算機時間的差值,用time來實作,因此srand((unsigned int)time(NULL));
4.判斷輸贏
我們先來看總共可以有幾種情況
1玩家贏 回傳#
2 電腦贏 回傳*
3 平局 回傳Q
4 以上三種都不是 繼續 回傳 C
在判斷行列是否為空的時候不能直接將一個確定的陣列填進去,只能依據回圈的特點判斷
回傳亦如此
//這是游戲的源檔案
#include "game.h"
//初始化棋盤
void InitBoard(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 Display_Board(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++)
{
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 Player_move(char board[ROW][COL], int row, int col)
{
printf("玩家走:>");
int i = 0;
int j = 0;
while (1)
{
scanf("%d%d", &i, &j);//scanf必須寫在回圈里否則里面的如果沒走if直接死回圈else
if (i >= 1 && i <= row && j >= 1 && j <= col)//在玩家眼中沒有元素小標的概念所以讓玩家正常輸入
{
if (board[i - 1][j - 1] == ' ')//我們將其轉換為計算機可以看懂的語言,如果為空就可以下棋
{
board[i - 1][j - 1] = '*';
break;
}
else//如果不是為空就表示已經被占
printf("此位置已經被占");
}
else
printf("坐標輸入錯誤請重新輸入");
}
}
//電腦走
void Computer_move(char board[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
while (1)
{
x = rand() % row;//隨機函式需要呼叫srand實作(在主函式內)引頭檔案<stdlib.h>(在頭檔案中)
y = rand() % col;//%col讓亂數的范圍控制在0~2的范圍內
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
//判斷輸贏
int is_full(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 is_win(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][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[0][0] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
{
return board[1][1];
}
int ret = is_full(board, row, col);
if (ret == 0)
{
return 'C';
}
else
{
return 'Q';
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/354779.html
標籤:其他
上一篇:舌尖上的C——三子棋的慢烹細作
