1. 程式人生 > 其它 >C語言實現 三子棋小遊戲(詳細+文尾附全程式碼)

C語言實現 三子棋小遊戲(詳細+文尾附全程式碼)

文章目錄

宣告

我寫的可能有點複雜,如果想直接看程式碼,可直接跳轉到完整的程式碼流程部分,將其拼起來即可!

多檔案

在開始講三子棋之前呢,先說說多檔案吧。我們平常寫程式碼的時候,如果程式比較大,那麼直接包含在一個檔案中就會顯得比較亂,並且不容易維護,這個時候就需要用到多檔案。使用多檔案的時候可以將整個程式拆分開來,比方說分為標頭檔案、函式檔案、測試檔案。當然如果有需要的話,還可以繼續細分。

在這裡我用了三個檔案來分,第一是test.c,用來存放主函式和選單,用來進行測試使用,第二是game.h用來存放標頭檔案、巨集定義以及函式宣告,第三是game.c用來存放各個函式。

三子棋遊戲實現講解

test.c

要實現三子棋遊戲,首先要一個可以用來測試我們的程式碼的主函式部分 。我們玩遊戲通常都會有選擇,所以我們就可以在主函式這裡提供一個選擇的權力:玩還是退出,遊戲嘛,當然是玩完一盤又一盤的所以可以通過迴圈來實現!

//測試三子棋遊戲

#include "game.h"

void menu()
{
	printf("**********************\n"
); printf("****1.play 0.exit***\n"); printf("**********************\n"); } void test() { int num; srand((size_t)time(NULL)); do { menu(); printf("請輸入你的選擇:>"); scanf("%d", &num); switch (num) { case 1: game(); break; case 0: printf
("退出遊戲\n"); break; default: printf("選擇有誤,請重新選擇:"); break; } } while (num); } int main() { test(); return 0; }

game.h

這是標頭檔案的程式碼

#pragma once
#define _CRT_SECURE_NO_WARNINGS 

#define ROW 3 //行數
#define COL 3 //列數

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

//宣告
void INITBUF(char buf[ROW][COL], int row, int col);
void DisplayBuf(char buf[ROW][COL], int row, int col);
void PlayerMova(char buf[ROW][COL], int row, int col);
void ComputerMove(char buf[ROW][COL], int row, int col);

//告訴我們四種遊戲狀態
//玩家贏-'*'
//電腦贏-'# '
//平局-'P'
//繼續-'C'
char whowin(char buf[ROW][COL], int row, int col);

三子棋是三行三列,所以我們設定全域性變數方便使用,這裡的’*’,’#’是為了區別雙方對弈的棋子,大家也可以用其他替換,方便觀看即可!首先我們初始化棋盤資訊(INITBUF(buf, ROW, COL)),然後我們打印出棋盤(DisplayBuf(buf, ROW, COL))隨便後我們便開始玩家下棋(PlayerMova(buf, ROW, COL)),和電腦下棋(ComputerMove(buf, ROW, COL)),每下一次棋列印棋盤。最後判斷輸贏(whowin(char buf[ROW][COL], int row, int col))

game.c

實現三子棋每一個步驟的函式程式碼
有點長,所以我分成一個個的發,這樣更直觀

INITBUF()

初始化棋盤,初始化為空格

void INITBUF(char buf[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			buf[i][j] = ' ';
		}
	}
}

DisplayBuf()

列印棋盤

void DisplayBuf(char buf[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 ", buf[i][j]);
			if (j < col - 1)
			{
				printf("|");
			}
		}
		puts("");
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
			puts("");
		}
	}
}

在這裡插入圖片描述

PlayerMova()

玩家下棋

void PlayerMova(char buf[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家走 >\n");
	while (1)
	{
		printf("請輸入座標(row col):");
		scanf("%d%d", &x, &y);
		//判斷座標是否在有效範圍
		//不是人人都懂陣列的用法,所以要確保座標的合法
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			//不是人人都懂陣列的用法,所以要確保座標的合法
			if (buf[x - 1][y - 1] == ' ')
			{
				buf[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("此座標已佔用\n");
			}
		}
		else
		{
			printf("輸入座標錯誤,請重新輸入!\n");
		}
	}
}

ComputerMove()

電腦下棋 採用隨機數的用法:引入標頭檔案 #include<time.h> ;產生隨機數:srand((size_t)time(NULL))在 test.c 函式裡引用

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

whowin()

判斷輸贏

//返回1:表示棋盤滿了
//返回0:表示棋盤沒滿
int pingju(char buf[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 (buf[i][j] == ' ')
			{
				return 0;//沒滿
			}
		}
	}
	return 1;//滿了
}
char whowin(char buf[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{

		if (buf[i][0] == buf[i][1] && buf[i][1] == buf[i][2] && buf[i][1] != ' ')
		{
			return buf[i][1];
		}
	}
	for (i = 0; i < col; i++)
	{

		if (buf[0][i] == buf[1][i] && buf[1][i] == buf[2][i] && buf[1][i] != ' ')
		{
			return buf[1][i];
		}
	}
	//對角線
	if (buf[0][0] == buf[1][1] && buf[1][1] == buf[2][2] && buf[1][1] != ' ')
	{
		return buf[1][1];
	}
	if (buf[2][0] == buf[1][1] && buf[1][1] == buf[0][2] && buf[1][1] != ' ')
	{
		return buf[1][1];
	}
	//判斷是否平局
	if (pingju(buf, ROW, COL) == 1)
	{
		return 'P';
	}
	return 'C';
}

game()

最後我們用**game()**將所有函式整合放到測試函式中,將其串起來

//整個遊戲的演算法實現
void game()
{
	char ret = 0;
	//陣列存放走出棋盤的資訊
	char buf[ROW][COL] = { 0 };
	//初始化棋盤
	INITBUF(buf, ROW, COL);
	//列印棋盤
	DisplayBuf(buf, ROW, COL);
	//下棋
	while (1)
	{
		//玩家下棋
		PlayerMova(buf, ROW, COL);
		DisplayBuf(buf, ROW, COL);
		ret = whowin(buf, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		//電腦下棋
		ComputerMove(buf, ROW, COL);
		DisplayBuf(buf, ROW, COL);
		ret = whowin(buf, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '*')
	{
		printf("你贏了,別得意了\n\n\n");
	}
	else if (ret == '#')
	{
		printf("你連人機都贏不了\n\n\n");
	}
	else
	{
		printf("和人機打成平手\n\n\n");
	}
}

完整的程式碼流程就是

1.測試函式部分 test.c

//測試三子棋遊戲

#include "game.h"

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

//整個遊戲的演算法實現
void game()
{
	char ret = 0;
	//陣列存放走出棋盤的資訊
	char buf[ROW][COL] = { 0 };
	//初始化棋盤
	INITBUF(buf, ROW, COL);
	//列印棋盤
	DisplayBuf(buf, ROW, COL);
	//下棋
	while (1)
	{
		//玩家下棋
		PlayerMova(buf, ROW, COL);
		DisplayBuf(buf, ROW, COL);
		ret = whowin(buf, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		//電腦下棋
		ComputerMove(buf, ROW, COL);
		DisplayBuf(buf, ROW, COL);
		ret = whowin(buf, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '*')
	{
		printf("你贏了,別得意了\n\n\n");
	}
	else if (ret == '#')
	{
		printf("你連人機都贏不了\n\n\n");
	}
	else
	{
		printf("和人機打成平手\n\n\n");
	}
}
void test()
{
	int num;
	srand((size_t)time(NULL));
	do
	{
		menu();
		printf("請輸入你的選擇:>");
		scanf("%d", &num);
		switch (num)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出遊戲\n");
			break;
		default:
			printf("選擇有誤,請重新選擇:");
			break;
		}
	} while (num);
}
int main()
{
	test();
	return 0;
}

標頭檔案部分 game.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS 

#define ROW 3
#define COL 3

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

//宣告
void INITBUF(char buf[ROW][COL], int row, int col);
void DisplayBuf(char buf[ROW][COL], int row, int col);
void PlayerMova(char buf[ROW][COL], int row, int col);
void ComputerMove(char buf[ROW][COL], int row, int col);

//告訴我們四種遊戲狀態
//玩家贏-'*'
//電腦贏-'# '
//平局-'P'
//繼續-'C'
char whowin(char buf[ROW][COL], int row, int col);

3.三子棋函式實現部分 game.c


#define _CRT_SECURE_NO_WARNINGS 
#include "game.h"

void INITBUF(char buf[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			buf[i][j] = ' ';
		}
	}
}

void DisplayBuf(char buf[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 ", buf[i][j]);
			if (j < col - 1)
			{
				printf("|");
			}
		}
		puts("");
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
			puts("");
		}
	}
}

void PlayerMova(char buf[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家走 >\n");
	while (1)
	{
		printf("請輸入座標(row col):");
		scanf("%d%d", &x, &y);
		//判斷座標是否在有效範圍
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (buf[x - 1][y - 1] == ' ')
			{
				buf[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("此座標已佔用\n");
			}
		}
		else
		{
			printf("輸入座標錯誤,請重新輸入!\n");
		}
	}
}
void ComputerMove(char buf[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("電腦走 >\n");
	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (buf[x][y] == ' ')
		{
			buf[x][y] = '#';
			break;
		}
	}
}

//返回1:表示棋盤滿了
//返回0:表示棋盤沒滿
int pingju(char buf[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 (buf[i][j] == ' ')
			{
				return 0;//沒滿
			}
		}
	}
	return 1;//滿了
}
char whowin(char buf[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{

		if (buf[i][0] == buf[i][1] && buf[i][1] == buf[i][2] && buf[i][1] != ' ')
		{
			return buf[i][1];
		}
	}
	for (i = 0; i < col; i++)
	{

		if (buf[0][i] == buf[1][i] && buf[1][i] == buf[2][i] && buf[1][i] != ' ')
		{
			return buf[1][i];
		}
	}
	//對角線
	if (buf[0][0] == buf[1][1] && buf[1][1] == buf[2][2] && buf[1][1] != ' ')
	{
		return buf[1][1];
	}
	if (buf[2][0] == buf[1][1] && buf[1][1] == buf[0][2] && buf[1][1] != ' ')
	{
		return buf[1][1];
	}
	//判斷是否平局
	if (pingju(buf, ROW, COL) == 1)
	{
		return 'P';
	}
	return 'C';
}

謝謝觀看!!!