目錄
1.前言
2.游戲準備
3.實作游戲的步驟
(1)生成選單界面
(2)游戲的實作邏輯
1.棋盤的初始化
2.生成九宮格
3.玩家下棋
4.電腦下棋
5.判斷輸贏
(3)額外補充(實作游戲先手或者后手的代碼)
(4)額外補充(實作游戲的美觀)system,sleep,
4.游戲全部代碼
1.game.h
2.game.c
3.chl.c
5.結尾
1.前言
這個游戲實作了人機對抗,且可選擇先手或者后手,就是電腦有點笨,下的棋是隨機的,所以還可以優化,
這個游戲我是通過c語言來實作的,還是存在一定的bug,這個bug就是當你輸入坐標的時候,輸入的不按照格式來,輸入整型外的東西,如a,b,就會死回圈列印輸入錯誤,但對于正常玩家來說,只要你別瞎輸,是不會觸及到bug的,因為博主實力有限,在經歷了無數次測驗發現了這個bug,但無可奈何我無法修復,但以后等我學到了更多的知識是一定會修復這個bug的,
2.游戲準備
1.游戲需要三個檔案,分別是game.h,game.c,chl.c.檔案名按照自己喜歡來,記得輸入英文,最好不要出現中文,為什么需要三個檔案呢?因為函式一般都是在頭檔案中宣告,其他檔案要用的話只需引.h的頭檔案即可,將測驗邏輯和實作邏輯分開來寫的原因是為了模塊分離,
(1)首先是頭檔案game.h,頭檔案里是用來存放函式的宣告,#define常量的定義,庫函式的參考的,
(2)其次是源檔案chl.c,這個檔案里面放的是游戲的測驗邏輯
(3)最后是源檔案game.c,這個檔案里面放的是游戲的實作邏輯
下面是引自己寫的頭檔案的方式,自己的頭檔案用“”參考,
#include"game.h"
3.實作游戲的步驟
(1)生成選單界面
先寫好主函式,如下圖所示:
int main()
{
test();
return 0;
}
再在test函式里寫好基本的邏輯:使用do while的回圈,如果用戶輸入1,則開始游戲,用戶輸入0,則退出游戲,若輸錯成其他數字,則可重新輸入,由于用到了多個選擇,所以可以使用Switch陳述句來實作,srand函式在后面有用,在這里先不講解,如下圖所示:
void test()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("請輸入:\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戲\n");
break;
default:
printf("請重新輸入\n");
break;
}
} while (input);
}
由于需要讓玩家知道選項,則需要選單,在這里是menu函式,此函式用來提示玩家,調動玩家的積極性的,
void menu()
{
printf("歡迎來到三子棋電腦版\n");
printf("你將與菜雞電腦pk三子棋\n");
printf("********請輸入:*******\n");
printf("********1.play*******\n");
printf("********0.exit*******\n");
printf("*********************\n");
}
(2)游戲的實作邏輯
當用戶輸入1以后,就會呼叫game()函式,在game()函式里面,我們需要實作棋盤的初始化,也就是將棋盤初始化為空白,還需實作棋盤的生成,即每個格子的分界線,如下圖所示

然后我們需要實作玩家下棋與電腦下棋的代碼,最后實作判斷誰勝利的條件,或者平局,下圖是game()函式的全部代碼,看不懂不用糾結,后面會逐一把它細節講解,
void game()
{
system("cls");//清除螢屏
char arr[ROW][COL];
Initboard(arr, ROW, COL);//初始化為空白,因為本來里面是有隨機值的,
Displayboard(arr, ROW, COL);//生成棋盤
char ret;
int a = 0;
printf("請選擇先手還是后手,先手輸入1,后手輸入2\n");
scanf("%d", &a);
while (1)
{
if (a == 1) {
player_move(arr, ROW, COL);//玩家下棋
system("cls");
Displayboard(arr, ROW, COL);
ret = is_win(arr, ROW, COL);
if (ret != 'C')
break;
computer(arr, ROW, COL);//電腦下棋
Sleep(500);//螢屏延遲500毫秒
system("cls");
Displayboard(arr, ROW, COL);
ret = is_win(arr, ROW, COL);
if (ret != 'C')
break;
}
else if(a==2)
{
computer(arr, ROW, COL);
Sleep(500);
system("cls");
Displayboard(arr, ROW, COL);
ret = is_win(arr, ROW, COL);
if (ret != 'C')
break;
player_move(arr, ROW, COL);
system("cls");
Displayboard(arr, ROW, COL);
ret = is_win(arr, ROW, COL);
if (ret != 'C')
break;
}
}
if (ret == '*')
{
printf("成功通關真牛逼\n");
}
else if (ret == 'o')
{
printf("你也太菜了,這都能輸\n");
}
else
{
printf("平局,你和入門級電腦的水平居然一樣\n");
}
}
1.棋盤的初始化
因為實作棋盤我們需要用到二維陣列,而二維陣列就得和行列掛鉤,ROW是行的意思,COL是列的意思,可定義寫成char arr[ROW][COL];先用#define定義這兩個值,方便日后若要修改,則只改#define后面的值也就跟著一起修改了,因為我們是寫九宮棋,所以定義為3即可,我們還將ROW,COL用row,col來接收,因為為了代碼的美觀,一般都選擇傳參,當然你如果不傳ROW,COL,對于邏輯上來說,是完全沒有問題的,但看上去就很齪,
#define ROW 3
#define COL 3
首先我們要實作初始化,在這里我們需要呼叫Initboard函式,這里我們用到了二維陣列以及二維陣列的傳參,下圖是Initboard函式的定義,用for回圈將二維陣列里的每個量都初始化為空格,避免了陣列中原來的隨機值的搗亂,
void Initboard(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++)
{
arr[i][j] = ' ';
}
}
}
2.生成九宮格
我們需要生成九宮格,如下圖所示:和上面一樣,將陣列傳參了過來,使用for回圈,輸入了|,-,來構建九宮格,重點就是九宮格
void Displayboard(char arr[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
printf(" %c | %c | %c \n", arr[i][0], arr[i][1], arr[i][2]);
if (i < row - 1)
printf("---|---|---\n");
}
}
3.玩家下棋
接下來就到了玩家下棋,也是傳陣列,通過回圈來輸入值,若是輸對了,則會break,但若是輸錯了,沒有關系,你可以再輸入一遍,此代碼的邏輯就是你輸入的坐標要在九宮格內部且不能輸入到已經有棋的地方,這里的重點是arr[x-1][y-1],因為陣列的下標是從0開始的,但是玩家寫坐標一定是從1開始的,所以我們需要考慮到玩家而改成x-1,y-1,來方便玩家,這里將玩家下的棋定做了*,
void player_move(char arr[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("請輸入你要下棋的坐標,如1,2這里是英文的逗號\n");
while (1)
{
scanf("%d,%d", &x, &y);
if (x <= 3 && x >= 1 && y <= 3 && y >= 1) {
if (arr[x - 1][y - 1] == ' ')
{
arr[x - 1][y - 1] = '*';
printf("\n");
break;
}
else
printf("輸入錯誤\n");
}
else
printf("輸入錯誤\n");
}
}
4.電腦下棋
電腦下棋本應該設定入門級,簡單級,困難級,但應博主實力有限,現只寫了入門級,也就是電腦下的棋是隨機的,所以我們需要用到隨機函式,rand(),srand(),time(),那就和上面的接上了,用此函式可以生成隨機值,但需要引頭檔案,stdlib.h和time.h,這里電腦下的棋用o表示,if陳述句限制了電腦只能下在空白的地方,而隨機值與行列取模限制了電腦只能下在九宮格內部,用while是因為萬一隨機值生成的位置有棋子了,則可以再次生成隨機值,下棋到別的地方去,
void computer(char arr[ROW][COL], int row, int col)
{
printf("電腦下棋\n");
while (1)
{
int x = rand() % ROW;
int y = rand() % COL;
if (arr[x][y] == ' ')
{
arr[x][y] = 'o';
break;
}
}
}
5.判斷輸贏
is_win函式是用來判斷輸贏的,當玩家贏的時候,回傳*,電腦贏的時候,回傳o,平局回傳A,繼續回傳C,使用for回圈來寫出當一行或者一列相等且不為空格則回傳那個符號,還用if陳述句將對角線相等寫了出來,如果全是*,則回傳*,則就是玩家贏,以此類推電腦贏,當棋盤滿了,卻還沒人贏的時候就會回傳A,那就平局了,否則就回傳C,那就繼續下棋,其中平局是用if_is_full()函式寫的,
char is_win(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2]&& arr[i][2]!=' ')
return arr[i][0];
}
for (j; j < col; j++)
{
if (arr[0][j] == arr[1][j] && arr[1][j] == arr[2][j]&&arr[2][j]!=' ')
return arr[0][j];
}
if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2]&& arr[2][2]!=' ')
return arr[0][0];
if (arr[2][0] == arr[1][1] && arr[1][1] == arr[0][2]&& arr[0][2]!=' ')
return arr[1][1];
if (1 == (if_is_full(arr, ROW, COL)))
return 'A';
return 'C';
}
int if_is_full(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++)
{
if (arr[i][j] == ' ')
return 0;
}
}
return 1;
}
while (1)
{
player_move(arr, ROW, COL);//玩家下棋
system("cls");
Displayboard(arr, ROW, COL);
ret = is_win(arr, ROW, COL);
if (ret != 'C')
break;
computer(arr, ROW, COL);//電腦下棋
Sleep(500);//螢屏延遲500毫秒
system("cls");
Displayboard(arr, ROW, COL);
ret = is_win(arr, ROW, COL);
if (ret != 'C')
break;
}
if (ret == '*')
{
printf("成功通關真牛逼\n");
}
else if (ret == 'o')
{
printf("你也太菜了,這都能輸\n");
}
else
{
printf("平局,你和入門級電腦的水平居然一樣\n");
}
(3)額外補充(實作游戲先手或者后手的代碼)
像下圖所示,加入一個if陳述句用來選擇,若是先人后電腦,則把人下棋放在電腦下棋前面,若是先電腦后人則是將電腦下棋放在人下棋前面,補充(當下棋完以后需要更新九宮格(Displayboard函式),然后判斷(if陳述句)是否要繼續(因為可能已經贏了或者平局了),然后才到下一個下棋,然后構成一個回圈,輪著下棋)
int a = 0;
printf("請選擇先手還是后手,先手輸入1,后手輸入2\n");
scanf("%d", &a);
while (1)
{
if (a == 1) {
player_move(arr, ROW, COL);//玩家下棋
system("cls");
Displayboard(arr, ROW, COL);
ret = is_win(arr, ROW, COL);
if (ret != 'C')
break;
computer(arr, ROW, COL);//電腦下棋
Sleep(500);//螢屏延遲500毫秒
system("cls");
Displayboard(arr, ROW, COL);
ret = is_win(arr, ROW, COL);
if (ret != 'C')
break;
}
else if(a==2)
{
computer(arr, ROW, COL);
Sleep(500);
system("cls");
Displayboard(arr, ROW, COL);
ret = is_win(arr, ROW, COL);
if (ret != 'C')
break;
player_move(arr, ROW, COL);
system("cls");
Displayboard(arr, ROW, COL);
ret = is_win(arr, ROW, COL);
if (ret != 'C')
break;
}
}
(4)額外補充(實作游戲的美觀)system,sleep,
為了實作游戲的美觀,我參考了system函式,用此函式需要參考頭檔案stdlib.h,system函式是用來執行系統命令的,system(“cls”)是用來清理螢屏的,sleep函式是用來使電腦暫停一段時間,單位為毫秒,時間寫在括號內部,使用sleep函式需要參考頭檔案windows.h,重點:sleep函式寫在c語言程式中s需要大寫,清理螢屏是為了螢屏上一直只有一個九宮格,與真實的九宮格游戲比較像,sleep函式是為了讓電腦下棋有一個程序,使體驗感更真實,
4.游戲全部代碼
1.game.h
#pragma once
#define ROW 3
#define COL 3
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void Initboard(char arr [ROW][COL], int row, int col);//初始化為空白
void Displayboard(char arr[ROW][COL],int row ,int col );
void player_move( char arr[ROW][COL],int row,int col);
void computer(char arr[ROW][COL], int row, int col);
char is_win(char arr[ROW][COL], int row, int col);
int if_is_full(char arr[ROW][COL], int row, int col);
2.game.c
#include"game.h"
void Initboard(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++)
{
arr[i][j] = ' ';
}
}
}
void Displayboard(char arr[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
printf(" %c | %c | %c \n", arr[i][0], arr[i][1], arr[i][2]);
if (i < row - 1)
printf("---|---|---\n");
}
}
void player_move(char arr[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("請輸入你要下棋的坐標,如1,2這里是英文的逗號\n");
while (1)
{
scanf("%d,%d", &x, &y);
if (x <= 3 && x >= 1 && y <= 3 && y >= 1) {
if (arr[x - 1][y - 1] == ' ')
{
arr[x - 1][y - 1] = '*';
printf("\n");
break;
}
else
printf("輸入錯誤\n");
}
else
printf("輸入錯誤\n");
}
}
void computer(char arr[ROW][COL], int row, int col)
{
printf("電腦下棋\n");
while (1)
{
int x = rand() % ROW;
int y = rand() % COL;
if (arr[x][y] == ' ')
{
arr[x][y] = 'o';
break;
}
}
}
char is_win(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2]&& arr[i][2]!=' ')
return arr[i][0];
}
for (j; j < col; j++)
{
if (arr[0][j] == arr[1][j] && arr[1][j] == arr[2][j]&&arr[2][j]!=' ')
return arr[0][j];
}
if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2]&& arr[2][2]!=' ')
return arr[0][0];
if (arr[2][0] == arr[1][1] && arr[1][1] == arr[0][2]&& arr[0][2]!=' ')
return arr[1][1];
if (1 == (if_is_full(arr, ROW, COL)))
return 'A';
return 'C';
}
int if_is_full(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++)
{
if (arr[i][j] == ' ')
return 0;
}
}
return 1;
}
3.chl.c
#include<stdio.h>
#include"game.h"
#include<windows.h>
void game()
{
system("cls");//清除螢屏
char arr[ROW][COL];
Initboard(arr, ROW, COL);//初始化為空白,因為本來里面是有隨機值的,
Displayboard(arr, ROW, COL);//生成棋盤
char ret;
int a = 0;
printf("請選擇先手還是后手,先手輸入1,后手輸入2\n");
scanf("%d", &a);
while (1)
{
if (a == 1) {
player_move(arr, ROW, COL);//玩家下棋
system("cls");
Displayboard(arr, ROW, COL);
ret = is_win(arr, ROW, COL);
if (ret != 'C')
break;
computer(arr, ROW, COL);//電腦下棋
Sleep(500);//螢屏延遲500毫秒
system("cls");
Displayboard(arr, ROW, COL);
ret = is_win(arr, ROW, COL);
if (ret != 'C')
break;
}
else if(a==2)
{
computer(arr, ROW, COL);
Sleep(500);
system("cls");
Displayboard(arr, ROW, COL);
ret = is_win(arr, ROW, COL);
if (ret != 'C')
break;
player_move(arr, ROW, COL);
system("cls");
Displayboard(arr, ROW, COL);
ret = is_win(arr, ROW, COL);
if (ret != 'C')
break;
}
}
if (ret == '*')
{
printf("成功通關真牛逼\n");
}
else if (ret == 'o')
{
printf("你也太菜了,這都能輸\n");
}
else
{
printf("平局,你和入門級電腦的水平居然一樣\n");
}
}
void menu()
{
printf("歡迎來到三子棋電腦版\n");
printf("你將與菜雞電腦pk三子棋\n");
printf("********請輸入:*******\n");
printf("********1.play*******\n");
printf("********0.exit*******\n");
printf("*********************\n");
}
void test()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("請輸入:\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戲\n");
break;
default:
printf("請重新輸入\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
5.結尾
若有錯誤或者哪里寫的不詳細請指出,因為實在是太忙沒時間更,若以后有時間,會多更新的,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/353457.html
標籤:其他
上一篇:IDEA插件分享(實用推薦)
下一篇:校園網斷線重連,用爬蟲來搞定!
