C語言經典小遊戲:五子棋

提示:此代碼需用Turbo C

/*加載頭文件*/
#include<stdio.h>
#include<stdlib.h>
#include<graphics.h>
#include<bios.h>
#include<conio.h>

/*編譯預處理,定義按鍵碼*/
#define LEFT 0x4b00 
#define RIGHT 0x4d00 
#define DOWN 0x5000 
#define UP 0x4800 
/*若想在遊戲中途退出, 可按 Esc 鍵*/
#define ESC 0x011b 
/*SPACE鍵表示落子*/
#define SPACE 0x3920

/*設置偏移量*/
#define OFFSET 20
#define OFFSET_x 4
#define OFFSET_y 3
/*定義數組大小*/
#define N 19 

/*定義全局變量*/
int status[N][N]; /*定義的數組,保存狀態*/
int step_x,step_y;/*行走的座標*/
int key ;         /*獲取按下的鍵盤的鍵*/
int flag;         /*玩家標誌*/

/*自定義函數原型*/
void DrawBoard();
void DrawCircle(int x,int y,int color);
void Alternation();
void JudgePlayer(int x,int y);
void Done();
int ResultCheck(int x,int y);
void WelcomeInfo();
void ShowMessage();

/*定義函數*/
/*顯示歡迎信息函數*/
void WelcomeInfo()
{
    char ch ;
    /*移動光標到指定位置*/
    gotoxy(12,4);
    /*顯示歡迎信息*/
    printf("Welcome you to gobang word!");
    gotoxy(12,6);
    printf("1.You can use the up,down,left and right key to move the chessman,");
    gotoxy(12,8);
    printf("  and you can press Space key to enter after you move it !");
    gotoxy(12,10);
    printf("2.You can use Esc key to exit the game too !");
    gotoxy(12,12);
    printf("3.Don not move the pieces out of the chessboard !");
    gotoxy(12,14);
    printf("DO you want to continue ?(Y/N)");
    ch=getchar();
    /*判斷程序是否要繼續進行*/
    if(ch=='n'||ch=='N')
    /*如果不繼續進行,則推出程序*/
    exit(0);
}

/*畫棋盤函數*/
void DrawBoard()
{
    int x1,x2;
    int y1,y2;
    /*設置背景色*/
    setbkcolor(2);
    /*設置線條顏色*/
    setcolor(1);
    /*設置線條風格、寬度*/
    setlinestyle(DOTTED_LINE,1,1);

    /*按照預設的偏移量開始畫棋盤*/
    for(x1=1,y1=1,y2=18;x1<=18;x1++)
        line((x1+OFFSET_x)*OFFSET,(y1+OFFSET_y)*OFFSET,(x1+OFFSET_x)*OFFSET,(y2+OFFSET_y)*OFFSET);
    for(x1=1,y1=1,x2=18;y1<=18;y1++)
        line((x1+OFFSET_x)*OFFSET,(y1+OFFSET_y)*OFFSET,(x2+OFFSET_x)*OFFSET,(y1+OFFSET_y)*OFFSET);
    /*將各個點的狀態設置爲0*/
    for(x1=1;x1<=18;x1++)
        for(y1=1;y1<=18;y1++)
            status[x1][y1]=0;

    /*顯示幫助信息*/
    setcolor(14);
    /*設置字體、大小*/
    settextstyle(1,0,1);
    outtextxy((19+OFFSET_x)*OFFSET,(2+OFFSET_y)*OFFSET,"Player key:");
    setcolor(9);
    settextstyle(3,0,1);
    outtextxy((19+OFFSET_x)*OFFSET,(4+OFFSET_y)*OFFSET,"UP--up ");
    outtextxy((19+OFFSET_x)*OFFSET,(6+OFFSET_y)*OFFSET,"DOWN--down ");
    outtextxy((19+OFFSET_x)*OFFSET,(8+OFFSET_y)*OFFSET,"LEFT--left");
    outtextxy((19+OFFSET_x)*OFFSET,(10+OFFSET_y)*OFFSET,"RIGHT--right");
    outtextxy((19+OFFSET_x)*OFFSET,(12+OFFSET_y)*OFFSET,"ENTER--space");
    setcolor(14);
    settextstyle(1,0,1);
    outtextxy((19+OFFSET_x)*OFFSET,(14+OFFSET_y)*OFFSET,"Exit:");
    setcolor(9);
    settextstyle(3,0,1);
    outtextxy((19+OFFSET_x)*OFFSET,(16+OFFSET_y)*OFFSET,"ESC");
}

/*畫圓函數*/
void DrawCircle(int x,int y,int color)
{
    setcolor(color);
    /*設置畫圓線條的風格,寬度,這裏設置爲虛線*/
    setlinestyle(SOLID_LINE,0,1);
    x=(x+OFFSET_x)*OFFSET;
    y=(y+OFFSET_y)*OFFSET;
    /*以(x,y)爲圓心,8爲半徑畫圓*/
    circle(x,y,8);
}



/*交換行棋方函數*/
void Alternation()
{
    if(flag==1)
        flag=2 ;
    else 
        flag=1 ;
}   

/*對不同的行棋方畫不同顏色的圓函數*/
void JudgePlayer(int x,int y)
{
    if(flag==1)
        DrawCircle(x,y,15);
    if(flag==2)
        DrawCircle(x,y,4);
}

/*判斷當前行棋方是否獲勝函數*/
int ResultCheck(int x,int y)
{
    int j,k;
    int n1,n2 ;
    while(1)
    {

        /*對水平方向進行判斷是否有5個同色的圓*/
        n1=0;
        n2=0;
        /*水平向左數*/
        for(j=x,k=y;j>=1;j--)
        {
            if(status[j][k]==flag)
                n1++;
            else
                break;
        }
        /*水平向右數*/
        for(j=x,k=y;j<=18;j++)
        {
            if(status[j][k]==flag)
            n2++;
            else
                break;
        }
        if(n1+n2-1>=5)
        {
            return(1);
        }

        /*對垂直方向進行判斷是否有5個同色的圓*/
        n1=0;
        n2=0;
        /*垂直向上數*/
        for(j=x,k=y;k>=1;k--)
        {
            if(status[j][k]==flag)
                n1++;
            else
                break ;
        }
        /*垂直向下數*/
        for(j=x,k=y;k<=18;k++)
        {
            if(status[j][k]==flag)
                n2++;
            else
                break ;
        }
        if(n1+n2-1>=5)
        {
            return(1);
        }

        /*從左上方到右下方進行判斷是否有5個同色的圓*/
        n1=0;
        n2=0;
        /*向左上方數*/
        for(j=x,k=y;(j>=1)&&(k>=1);j--,k--)
        {
            if(status[j][k]==flag)
                n1++;
            else
                break;
        }
        /*向右下方數*/
       for(j=x,k=y;(j<=18)&&(k<=18);j++,k++)
        {
            if(status[j][k]==flag)
                n2++;
            else
                break;
        }
        if(n1+n2-1>=5)
        {
            return(1);
        }

        /*從右上方到左下方進行判斷是否有5個同色的圓*/
        n1=0;
        n2=0;
        /*向右上方數*/
        for(j=x,k=y;(j<=18)&&(k>=1);j++,k--)
        {
            if(status[j][k]==flag)
                n1++;
            else
                break;
        }
        /*向左下方數*/
        for(j=x,k=y;(j>=1)&&(k<=18);j--,k++)
        {
            if(status[j][k]==flag)
                n2++;
            else
                break;
        }
        if(n1+n2-1>=5)
        {
            return(1);
        }
        return(0);
    }
}

/*執行下棋函數*/
void Done()
{
    int i ;
    int j ;
    /*根據不同的key值進行不同的操作*/
    switch(key)
    {
    /*如果是向左移動的*/
    case LEFT:
        /*如果下一步超出棋盤左邊界則什麼也不作*/
        if(step_x-1<0)
            break ;
        else 
        {
            for(i=step_x-1,j=step_y;i>=1;i--)
                if(status[i][j]==0)
                {
                    DrawCircle(step_x,step_y,2);
                    break ;
                }
            if(i<1)
                break ;
            step_x=i ;
            JudgePlayer(step_x,step_y);
            break ;
        }
    /*如果是向右移動的*/
    case RIGHT :
        /*如果下一步超出棋盤右邊界則什麼也不作*/
        if(step_x+1>18)
            break ;
        else
        {
            for(i=step_x+1,j=step_y;i<=18;i++)
                if(status[i][j]==0)
                {
                    /*每移動一步畫一個圓,顯示移動的過程*/
                    DrawCircle(step_x,step_y,2);
                    break ;
                }
            if(i>18)break ;
                step_x=i ;
            /*根據不同的行棋者畫不同顏色的圓*/
            JudgePlayer(step_x,step_y);
            /*顯示行棋一方是誰*/
            break ;
        }
    /*如果是向下移動的*/
    case DOWN :
        /*如果下一步超出棋盤下邊界則什麼也不作*/
        if((step_y+1)>18)
            break ;
        else 
        {
            for(i=step_x,j=step_y+1;j<=18;j++)
            if(status[i][j]==0)
            {
                DrawCircle(step_x,step_y,2);
                break ;
            }
            if(j>18)break ;
                step_y=j ;
            JudgePlayer(step_x,step_y);
            break ;
        }
    /*如果是向上移動的*/
    case UP :
        /*如果下一步超出棋盤上邊界則什麼也不作*/
        if((step_y-1)<0)
            break ;
        else 
        {
            for(i=step_x,j=step_y-1;j>=1;j--)
                if(status[i][j]==0)
                {
                    DrawCircle(step_x,step_y,2);
                    break ;
                }
            if(j<1)break ;
                step_y=j ;
            JudgePlayer(step_x,step_y);
            break ;
        }
    /*如果是退出鍵*/
    case ESC :
        break ;
    /*如果是確定鍵*/
    case SPACE:
        /*如果操作是在棋盤之內*/
        if(step_x>=1&&step_x<=18&&step_y>=1&&step_y<=18)
        {
            /*按下確定鍵後,如果棋子當前位置的狀態爲0*/
            if(status[step_x][step_y]==0)
            {
                /*則更改棋子當前位置的狀態在flag,表示是哪個行棋者行的棋*/
                status[step_x][step_y]=flag ;
                /*如果判斷當前行棋者獲勝*/
                if(ResultCheck(step_x,step_y)==1)
                {
                    /*以指定頻率打開PC揚聲器*/
                    sound(1000);
                    /*揚聲器的發生時間,爲1秒鐘*/
                    delay(1000);
                    nosound();
                    gotoxy(30,4);
                    setbkcolor(BLUE);
                    /*清除圖形屏幕*/
                    cleardevice();
                    /*爲圖形輸出設置當前視口*/
                    setviewport(100,100,540,380,1);
                    /*綠色實填充*/
                    setfillstyle(1,2);
                    setcolor(YELLOW);
                    rectangle(0,0,439,279);
                    floodfill(50,50,14);
                    setcolor(12);
                    settextstyle(1,0,5);
                    /*三重筆劃字體, 水平放大5倍*/
                    outtextxy(20,20,"Congratulation !");
                    setcolor(15);
                    settextstyle(3,0,4);
                    /*如果是Player1獲勝,顯示獲勝信息*/
                    if(flag==1)
                    {
                        /*無襯筆劃字體, 水平放大5倍*/
                        outtextxy(20,120,"Player1 win the game !");
                    }
                    /*如果是Player1獲勝,顯示獲勝信息*/
                    if(flag==2)
                    {
                        /*無襯筆劃字體, 水平放大5倍*/
                        outtextxy(20,120,"Player2 win the game !");
                    }
            
                    setcolor(14);
                    settextstyle(2,0,8);
                    getch();
                    exit(0);
                }
                /*如果當前行棋者沒有獲勝,則交換行棋方*/
                Alternation();
                /*提示行棋方是誰*/
                ShowMessage();
                break;
            }
       }
       else
          break ;
   }
}

/*顯示行棋方函數*/
void ShowMessage()
{
    /*輪到Player1行棋*/
    if(flag==1)
    {
        setcolor(2);
        settextstyle(1,0,1);
        gotoxy(100,30);
        /*覆蓋原有的字跡*/
        outtextxy(100,30,"It's turn to Player2 !");
        setcolor(12);
        settextstyle(1,0,1);
        outtextxy(100,30,"It's turn to Player1 !");
    }
    /*輪到Player2行棋*/
    if(flag==2)
    {
        setcolor(2);
        settextstyle(1,0,1);
        /*覆蓋原有的字跡*/
        outtextxy(100,30,"It's turn to Player1 !");
        setcolor(12);
        settextstyle(1,0,1);
        gotoxy(100,20);
        outtextxy(100,30,"It's turn to Player2 !");

    }
}

/*主函數*/
int main()
{
    int gdriver;
    int gmode;
    int errorcode;
    /*清空文本模式窗口*/
    clrscr();
    /*顯示歡迎信息*/
    WelcomeInfo();
    gdriver=DETECT;
    gmode=0;
    /*初始化圖形系統*/
    initgraph(&gdriver,&gmode,"");
    /*返回最後一次不成功的圖形操作的錯誤代碼*/
    errorcode=graphresult();
    if (errorcode!= grOk)  
    {
        /*根據錯誤代碼輸出錯誤信息串*/
        printf("\nNotice:Error occured when grphics initialization: %s\n",grapherrormsg(errorcode));
        printf("Press any key to quit!");
        getch(); 
        exit(1);            
    }

    /*設置flag初始值,默認是Player1先行*/
    flag=1;
    /*畫棋盤*/
    DrawBoard();
    ShowMessage();
    do 
    {
        step_x=0 ;
        step_y=0 ;
        JudgePlayer(step_x-1,step_y-1);
        do 
        {
            /*如果沒有鍵按下,則bioskey(1)函數將返回0*/
            while(bioskey(1)==0);
            /*獲取從鍵盤按下的鍵值*/
            key=bioskey(0);
            /*根據獲得的鍵值進行下棋操作*/
            Done();
        }while(key!=SPACE&&key!=ESC);
    }while(key!=ESC);
    /*關閉圖形系統*/
    closegraph();
    return 0;
}




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