国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

三子棋游戲設計及代碼實現

Ku_Andrew / 3139人閱讀

摘要:三子棋三子棋游戲介紹規則游戲設計思路代碼分析文件代碼分析。玩家下棋實現。三子棋是一種民間傳統游戲,又叫九宮棋圈圈叉叉一條龍井字棋等。落子后打印棋盤以顯示。假設平局時判定輸贏的函數返回后面代碼實現時詳細講。

?三子棋游戲介紹

是黑白棋的一種。
三子棋是一種民間傳統游戲,又叫九宮棋、圈圈叉叉、一條龍、井字棋等。
將正方形對角線連起來,相對兩邊依次擺上三個雙方棋子,只要將自己的三個棋子走成一條線,對方就算輸了。但是,有很多時候會出現和棋的情況。

?規則?

如果兩個人都掌握了技巧,那么一般來說就是平(和)棋。一般來說,第二步下在中間最有利(因為第一步不能夠下在中間),下在角上次之,下在邊上再次之。最大的好處就是隨便找個地方就可以玩這個簡單而有趣的游戲了。

?游戲設計思路

  1. 首先需要一個菜單欄,供玩家選擇進入游戲或者退出游戲。
  2. 這里提供選擇:
    • 進入游戲
    1. 退出游戲

其他輸入 - 重新選擇(循環實現)

在進入游戲后:

將游戲的實現使用到的函數封裝在game.c文件中。

函數實現功能:

  1. 制作一個棋盤。

如下:

可通過函數中循環控制實現。

制作棋盤分為:

  • 將棋盤初始化。
  • 將棋盤打印在控制臺。
  1. 模擬下棋對戰過程:
  • 由玩家先手落子。

落子后打印棋盤以顯示。

  • 電腦自動隨機落子。

直到某一方勝利或者和棋。

  1. 判斷游戲輸贏情況。

通過行、列、對角線落子相同形式判別勝利。


因為一個程序需要對實現功能的部分進行封裝,所以我們在這里將整個程序分為3個文件:

  1. test.c文件 - 功能是實現進入主頁面并實現調用各種函數。
  2. game.c文件 - 功能是實現各個函數的邏輯,這也是進行封裝的目的:保留實現邏輯,只展示功能實現。
  3. game.h文件 - 功能是存放預編譯指令、聲明指令、全局變量等等。


?代碼分析?

?1. test.c文件代碼分析。

?開始游戲。

游戲開始時,要確保4點:

  1. 玩家輸入1 - 進入游戲。
  2. 玩家輸入0 - 退出游戲。
  3. 玩家輸入其他 - 重新輸入。
  4. 游戲結束后可以再次進行選擇是否繼續游戲。
int main(){	int input = 0;	do	{		menu();		printf("請選擇:>");		scanf("%d", &input);		switch (input)		{		case 1:			game();			break;		case 0:			printf("您已退出游戲。/n");			break;		default:			printf("選擇錯誤,請重新輸入。/n");			break;		}	} while (input);		return 0;}

?菜單顯示。

這里只需要打印一個簡易菜單即可,如果有前端知識可以設計出更好的界面。

void menu(){	printf("**********************************/n");	printf("************  1.play  ************/n");	printf("************  0.exit  ************/n");	printf("**********************************/n");}

實現代碼效果:

  1. 玩家輸入1:

  1. 玩家輸入0:


3. 玩家輸入其他:

上面展示了玩家輸入0,1,其他時的不同效果。

如輸入其他時,會通過循環一直輸入,直到輸入(0/1)時,進入游戲或者退出游戲。

?進入游戲。

在進入游戲后,需要通過對不同的函數進行封裝實現,完成我們想要的功能:

  1. 初始化棋盤。
  2. 實現打印棋盤的函數。
  3. 人機循環對弈直到分出結果。

第三點需要注意:

因為不知道什么時候分出結果,所以需要在每一次下完棋之后進行判斷是否分出結果。

結果的可能有4種:

  1. 玩家贏。 – 假設玩家棋子為 ‘ * ’;
  2. 電腦贏。 – 假設電腦棋子為 ‘ # ’;
  3. 平局。 – 假設平局時判定輸贏的函數返回 ‘ C ’;
    (后面代碼實現時詳細講。)
  4. 游戲繼續。 – 假設函數返回 ‘ Q ’。
    (即棋盤未被填滿且尚未分出勝負)
void game(){	//三子棋過程	char board[ROW][COL]; //棋盤數組	//初始化棋盤 - board的元素全都給空格	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);		ret = IsWin(board, ROW, COL);		if (ret != "C")		{			break;		}	}	if (ret == "*")	{		printf("玩家贏/n");	}	else if (ret == "#")	{		printf("電腦贏/n");	}	else	{		printf("平局/n");	}}

這里將不同函數實現的功能一一說明:

  • 初識化棋盤。
InitBoard(board, ROW, COL);

整個棋盤是通過一個二維數組實現的,棋盤初始化即指將二維數組中的所有元素置成空格,因為空格打印在控制臺上是不可見的。

  • 打印棋盤。
DisplayBoard(board, ROW, COL);

因為棋盤初始化之后全部是空格,是不可見的,所以我們需要打印棋盤的函數對棋盤做一些控制,讓他變成我們希望的樣子。

實現模板:

  • 開始下棋。

下棋部分又分為玩家下棋和電腦下棋。

  1. 玩家下棋。
  2. 電腦下棋。
PlayerMove(board, ROW, COL);  //玩家下棋ComputerMove(board, ROW, COL);  //電腦下棋

二者的邏輯實現不同,所以封裝為不同的函數實現。

當然,在實現完下棋之后需要再次調用棋盤打印函數,一來一回的在界面上出現,增加代碼的趣味性。

  • 判斷輸贏函數。
ret = IsWin(board, ROW, COL);

這個函數需要有返回值來告訴我們游戲的結果,四種結果上面已經提到過。

1. 玩家贏。 – 假設玩家棋子為 ‘ * ’;
2. 電腦贏。 – 假設電腦棋子為 ‘ # ’;
3. 平局。 – 假設平局時判定輸贏的函數返回 ‘ C ’;
4. 游戲繼續。 – 假設函數返回 ‘ Q ’。
(即棋盤未被填滿且尚未分出勝負)


?2. game.c文件代碼分析。

- ?初識化二維數組,即初始化棋盤。

只需要控制循環即可遍歷整個二維數組中的所有元素,將他們賦值為空格即可。

void InitBoard(char board[ROW][COL], int row, int col){	int i = 0;	for (i = 0; i < row; i++)	{		int j = 0;		for (int j = 0; j < col; j++)		{			board[i][j] = " ";		}	}}

這里提一下ROW和COL分別表示棋盤的長和寬,在game.h文件里聲明了,后面介紹,這里只需要直到他們的值都是3即可,因為三子棋棋盤就是3?3的。

- ?打印棋盤函數。

打印函數實現:

  1. 打印棋盤首先我們要把每一個數組里的元素打印出來,為了使顯示美觀,可控制為“ %c ”,%c左右兩側各加一個空格。
  2. 當列數小于2時打印‘ | ’,這樣就會在每列打印時產生兩個豎分隔線。
  3. 當行數小于2時打印‘ — ’,這樣就會在第一行第二行和第二行第三行之間打印一行橫分割線,在實現橫分割線的同時通過第二點實現打印
    ‘ - - - | - - - | - - - ’。
  4. 注意每一行打印完之后進行換行操作。
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. 玩家視角的9宮格是從(1,1) - > (3,3)的,但是我們程序員視角的二維數組下標是(0,0) -> (2,2)的,所以定義x和y坐標之后,將其作為數組下標時要減一。即
board[x - 1][y - 1];
  1. 玩家落子是手動輸入坐標的,所以要考慮到代碼的健壯性,即玩家輸入的坐標不在(1,1)->(3,3)之間的情況下,應該輸出警告,并通過循環重新輸入。
  2. 還需要注意,下棋是一個雙向反復的過程,如果落子時落子的坐標合法,但是該坐標已經被落過子了,則也應該提出警告,并利用循環重新輸入。
void PlayerMove(char board[ROW][COL], int row, int col){	int x = 0;	int y = 0;	while (1)	{		printf("玩家走:/n");		printf("請輸入坐標:>");		scanf("%d %d", &x, &y); // 2 1 --> 1 0		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");		}	}}

因為存在輸入坐標落過子或者非法需要重新輸入的原因,所以這里的循環判定條件為1,直到成功落子才break跳出循環。

- ?電腦落子函數實現。

這里需要說明,該代碼是基于C語言實現的,電腦落子屬于人工智能及算法范疇,不予討論。
這里電腦落子通過時間軸生成偽隨機數進行坐標落子。

電腦落子不存在坐標非法的情況,因為我們可以通過對其取模進行控制。

但確實也會存在落子處被占用的情況,所以也需要利用循環重新隨機一個數,所以隨機數代碼應該放在循環體里面,這是一個小細節,需要注意。

void ComputerMove(char board[ROW][COL], int row, int col){	printf("電腦走:>/n");	while (1)	{		int x = rand() % row;		int y = rand() % col;		if (board[x][y] == " ")		{			board[x][y] = "#";			break;		}	}}

如果成功找到位置,就將 ’ # "賦給該坐標位置,然后break結束。

- ?判斷輸贏函數。

判斷輸贏有三種情況:

  1. 行相等。 - 通過循環實現。
  2. 列相等。 - 通過循環實現。
  3. 對角線相等 - 兩個對角線都要考慮。
  4. 需要多調用一個函數來判斷棋盤是否被下滿了。
    • 如果被下滿了,并且沒有出現贏家,則返回’ Q ’ - 表示平局。
    • 如果沒有被下滿,并且沒有出現贏家,則返回’ C ’ - 表示繼續游戲。
char IsWin(char board[ROW][COL], int row, int col){	//1.判斷輸贏	//2.判斷平局	//3.游戲繼續	//行	int i = 0;	for (i = 0; i < row; i++)	{		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][2] != " ")		{			return board[i][0];		}	}	//列	for (i = 0; i < col; i++)	{		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[2][i] != " ")		{			return board[0][i];		}	}	//對角線	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] != " ")	{		return board[0][0];	}	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != " ")	{		return board[0][2];	}	//判斷平局	if (IsFull(board, row, col))	{		return "Q";	}	//游戲繼續	return "C";}

需要注意一個小細節,判斷行、列、對角線相等時要判斷他們不等于’ ",即不為空格,因為我們初始化的時候把所有元素都初始化為空格了,不然的話直接就判斷結束了,屬于bug代碼。

- ?在判斷輸贏函數中調用的判斷棋盤是否滿的函數。

注意問題:
只需要遍歷二維數組中的每一個元素,如果遇到了一個空格,則返回0,代表棋盤未滿,如果遍歷完所有元素之后都沒有發現空格,則代表棋盤已被下滿,返回1。

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; //滿了}

需要注意的問題是返回值是0或者1,所以定義函數的類型是int類型。


?3. game.h代碼分析

這個文件放的是預編譯命令和聲明函數等等指令。

預處理命令包括:

  1. 文件包含。
  2. #define引用。
  3. 條件編譯。
#pragma once#include #include #include #define ROW 3#define COL 3//初始化棋盤void InitBoard(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);//判斷游戲輸贏//要返回4種不同的狀態//玩家贏 - "*"//電腦贏 - "#"//平局 - "Q"//繼續 - "C"char IsWin(char board[ROW][COL], int row, int col);

因為is_full函數是在game.c文件中被調用并且是在game.c文件中能夠被定義的,所以不需要在game.h文件中聲明。

??總結

???以上就是本文全部內容,整個游戲代碼源碼將會放在全文最后ps部分,如果有講的不對或者不充分的地方希望大家可以在評論區留言,如果覺得博主寫的還行可以留下各位的?點贊?+?關注?+?收藏?嗷~

??♂?PS(源代碼)

?test.c
#define _CRT_SECURE_NO_WARNINGS 1#include "game.h"void menu(){	printf("**********************************/n");	printf("************  1.play  ************/n");	printf("************  0.exit  ************/n");	printf("**********************************/n");}void game(){	//三子棋過程	char board[ROW][COL]; //棋盤數組	//初始化棋盤 - board的元素全都給空格	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);		ret = IsWin(board, ROW, COL);		if (ret != "C")		{			break;		}	}	if (ret == "*")	{		printf("玩家贏/n");	}	else if 
                 
               
              

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/121418.html

相關文章

  • 《C語言入門》三子C語言實現(詳細版)

    摘要:簡單介紹了三子棋原理后接下來為大家講解分步目標及代碼如何實現。電腦下棋我們實現了玩家和電腦的下棋后,我們需要編寫一個函數來判斷雙方的輸贏。我們使用函數來實現這一目標。 目錄 1.三子棋原理 2.分塊代碼實現 3.總結 1.首先向大家介紹一下三子棋的原理 首先我們需要有一個棋盤,初始時棋...

    妤鋒シ 評論0 收藏0
  • 用C語言實現三子

    摘要:文章目錄三子棋的設置的內容設置的設置棋盤的內容棋盤以及棋盤的初始化打印棋盤下棋步驟玩家下棋電腦下棋判斷是否勝利三子棋三子棋的規則是在的棋盤里,雙方輪流下子以和表示,先將個子連成一條線橫豎斜都可以的一方獲勝下面是三子棋語 ...

    vspiders 評論0 收藏0
  • 三子游戲

    摘要:三子棋小游戲三子棋游戲簡介一分析及實現棋盤落子判斷輸贏二程序演示三完整代碼總結三子棋游戲簡介這是一個簡單的三子棋小游戲,估計大家小時候都玩兒過,只要能連成三個,無論是行,列還是對角線,就可以勝利了。 ...

    liuyix 評論0 收藏0
  • 《C語言入門》掃雷小游戲C語言實現

    摘要:條消息語言入門三子棋語言實現詳細版的博客博客條消息語言入門三子棋語言實現詳細版的博客博客我們將雷盤初始化為統一的符號。 目錄 1.原理簡介 2.分布目標及代碼實現 3.總結 1.原理簡介 ?首先我們需要一個空的雷盤,在其中隨機埋入十枚雷,當我們排這顆雷時,若此位置為雷,則游戲失敗,若不...

    caige 評論0 收藏0
  • 三子(井字)】如何用C語言實現

    摘要:三子棋目錄一問題介紹三子棋,在民間又叫井字棋。因為人們在游玩時常常不畫棋盤的邊框,正如漢字中的井字,多稱為井字棋。 三子棋 目錄 一、問題介紹 ? ? ? ? 三子棋,在民間又叫井字棋。因為人們在游玩時常常不畫棋盤的邊框,正如漢字中的井字,多稱為井字棋。 三子棋的游戲規則十分的簡單: ...

    jsbintask 評論0 收藏0

發表評論

0條評論

Ku_Andrew

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<