三子棋——C語言實現

一. 三子棋簡單概述

     相信大部分人都玩過五子棋,也知道五子棋的規則與玩法。而今天的三子棋就是簡易版的五子棋。

     首先,在一張3*3的棋盤上,雙方先後落子,誰先形成三個相同且相連的棋,誰就贏得了比賽。可以是一排或者一列三個相同,也可以是兩個對角線上的三個棋子相同。如下圖所示,綠方獲勝。

從上方的簡單描述中,我們也可以大體知道,c語言實現這樣一個單機版的三子棋是什麼樣的。接下來我們就整體說一下思路。

 二. c 語言實現三子棋的總體思路

  1. 首先,我們需要一個菜單界面,來提示用戶進行遊戲或者退出。
  2. 主函數裏分爲開始遊戲(game()函數)和退出,並且不同的情況調用他們各自的函數來實現功能。
  3. 在game()函數函數裏, 首先需要一個3*3的二維數組當作棋盤,並且需要對棋盤初始化,因爲雙方沒落子之前棋盤是空的,所以我們需要將棋盤的每個位置初始化爲空格字符(  InitBoard()函數 )。遊戲一旦開始,我們需要將初始化後的棋盤顯示( ShowBoard()函數 )在用戶面前。接下來讓用戶輸入自己所要落子的位置,並且判斷該位置是否合法。用戶落子之後,需要判斷當前棋盤是否已滿,或者是否有人已經贏得比賽( Judge()函數 )。同樣,在用戶落子之後,電腦通過生成隨機數來落子。
  4. 最後,通過循環來依次落子。

三. 採取分文件來實現該項目

如上圖所示,就是今天分文件項目的三大部分。下面就每個文件裏邊的內容以及函數的具體實現一一說明。

1.main.c文件

  此文件主要是來實現三子棋的總體框架,調用封裝好的各個接口。

#include"Game.h"

int main()
{
	
	int quit = 0;
	int select = 0;
	
	while (!quit)
	{
		menu();
		printf("\nPlease enter your choice:");
	    scanf("%d", &select);
		switch (select)
		{
		  case 1:
			  game();
			  break;
		  case 2:
			  quit = 1;
			  break;
		  default:
			  printf("\nInput Error,please enter your choice again:");
			  break;
		}
	}

	system("pause");
	return 0;
}

#include"Game.h"就是我們聲明瞭各大接口函數,以及宏定義、頭文件的聲明。quit是用來用戶是否要退出遊戲的一個標誌,用戶選擇2,則quit置爲1,!quit就是0,即條件不成立退出循環。

 

2.Game.h頭文件

此文件聲明瞭各大接口函數,以及宏定義、頭文件的聲明。

#ifndef _GAME_H_
#define _GAME_H_


#include<stdio.h>
#include<Windows.h>
#include<time.h>
#pragma warning(disable:4996)

#define COL 3  
#define ROW 3
#define  PLAYER 'X'  //用戶落子用X字符顯示
#define  COMPUTER 'O' //電腦落子用O字符顯示
#define N '1'
#define F '2'

//菜單函數
 void menu();
 //遊戲函數
 void game();
 //初始化棋盤的函數
 void  InitBoard(char board[][ROW], int row, int col);
 //打印棋盤的函數
 void ShowBoard(char board[][ROW], int row, int col);
 //電腦落子函數
 void  ComputerPlay(char board[][ROW], int row, int col);
 //判斷棋盤是否滿 或者此時是否有人贏得比賽
 char Judge(char board[][ROW], int row, int col);

#endif

代碼裏聲明的每個函數的功能我都一一標註過~~~。

2.Game.c文件

大頭來了!!

首先說一下game()函數,此函數可是整個遊戲的中心,能否快樂下棋,就看此成敗!

void game()
{
	char result ;
    //中隨機數種子(爲後面電腦隨機生成座標種下隨機數種子)
	srand((unsigned)time(NULL));
    //定義3*3的棋盤
	char board[ROW][COL];
	//初始化錶盤
	InitBoard(board, ROW, COL);

    //通過循環落子
	do{
		//給用戶顯示錶盤
		ShowBoard(board, ROW, COL);
		printf("\n");
		printf("請落子:");
		int x = 0;
		int y = 0;
		scanf("%d %d", &x, &y);
		printf("\n");
       //判斷落子座標是否合法
		if (x<1 || x>3 || y<1 || y>3)
		{
			printf("您輸入的位置有誤,請重新輸入!\n");
			continue;
		}
		if (board[x - 1][y - 1] !=' ')
		{
			printf("該位置已經被佔用,請重新輸入!\n");
			continue;
		}
		
		//用戶落子(修改棋盤界面,讓用戶看到下棋的過程)
		board[x - 1][y - 1] = PLAYER;
		
        //判斷棋盤是否下滿或者有人是否贏了
		 result = Judge(board, ROW, COL);
		 if (result != 'N')//棋盤滿了或者贏了
		 {
				ShowBoard(board, ROW, COL);
				printf("\n");
				break;
		 }
			
		//電腦落子
		ComputerPlay(board, ROW, COL);

		
		result = Judge(board, ROW, COL);

		if (result != 'N')
		{
           ShowBoard(board, ROW, COL);
		   printf("\n");
		   break;
		}
		
	} while (1);

	if (result == PLAYER)
	{
	printf("\t恭喜你!,你贏了!\n\n");
	
	}
	else if (result == COMPUTER){
	printf("\t不好意思,電腦贏了!\n\n");

	}
	else {
	printf("\t玩的不錯,平局!\n\n");

	}
	printf("你玩的不錯要不要再來一把!!!~~~~~\n");
}

思路我在第二部分也說了,具體到每行代碼的註釋已經標註~~

菜單函數menu()

void menu()
{
	printf("\n\n");
	printf("\t\t#######################################################\n");
	printf("\t\t#######################################################\n");
	printf("\t\t#######                                        ########\n");
	printf("\t\t#######   Welcome to three-and-crosses world!  ########\n");
	printf("\t\t#######                                        ########\n");
	printf("\t\t#######                                        ########\n");
	printf("\t\t#######   1.PLAY                      2.EXIT   ########\n");
	printf("\t\t#######                                        ########\n");
	printf("\t\t#######################################################\n");
	printf("\t\t#######################################################\n\n");
}

運行結果: 

初始化棋盤函數InitBoard()

也就是將九個位置初始化爲空格

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

打印棋盤函數 ShowBoard()

void ShowBoard(char board[][ROW], int row, int col)
{
	int i = 0;
	//printf("%d", row);
	printf("     1    2    3\n");
	printf("   ---------------\n");
	for (; i < row; i++)
	{
		printf(" %d |", i + 1);
		for (int j = 0; j < col; j++)
		{
			printf(" %c | ", board[i][j]);
		}
		printf("\n   ---------------\n");
	}

}

運行結果:

電腦落子函數ComputerPlay()

//電腦下棋
void  ComputerPlay(char board[][ROW], int row, int col)
{
	while (1)
	{
     //產生1-2的隨機數
		int random_x = rand() % row;
		int random_y = rand() % col;
       //判斷此處是否已落子
		if (board[random_x][random_y] == ' ')
		{
			board[random_x][random_y] = COMPUTER;
			break;
		}
	}
}

判斷是此時棋盤是否放滿Judge()函數

//判斷是此時棋盤是否放滿(N-->沒滿,繼續走,F--->滿了退出)
char Judge(char board[][ROW], int row, int col)
{
	int i = 0;
	for (; i < row; i++)
	{
		//判斷每行
		if (board[i][1] != ' '&& board[i][1] == board[i][0] && board[i][0] == board[i][2])
		{
			return board[i][1];
			
		}
		//判斷每列
		if (board[1][i] != ' ' && board[1][i] == board[0][i] && board[0][i] == board[2][i])
		{
			return board[1][i];
		}
		
		
	}
	//判斷對角線
	if ((board[1][1] != ' ' && board[1][1] == board[0][0] && board[0][0] == board[2][2]) || \
		(board[1][1] != ' ' &&board[1][1] == board[2][0] && board[2][0] == board[2][2]))
	{
		return board[1][1];
	}


	//棋盤全部下滿 返回F ;沒滿 返回N
	if (board[1][1] != ' '&& board[0][0] != ' '&&  board[2][2] != ' '&&  board[1][2] != ' '&& \
		board[0][2] != ' '&&  board[1][0] != ' '&&board[2][0] != ' '&&board[2][1] != ' '&&board[0][1] != ' ')
	{
		return 'F';
	}
	return 'N';
}

運行結果

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章