⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1234.c

📁 五子棋 五子棋 五子棋 五子棋
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <stdlib.h>
#include <bios.h>
#include <graphics.h>
#include<malloc.h>
/*
 * 对应键盘键的十六进制数字
 */
#define ESC 0x11b
#define UP 0x4800
#define DOWN 0x5000
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define BLANK 0x3920
#define PLAYER1 1
#define PLAYER2 2
#define COMPUTER 2
#define LENGTH 15
#define SEARCH_DEEP 2
/*
 * 用来在函数can_expand()查找可以扩展的节点步长
 */
#define STEP 1
/************全局变量定义***************/
int             x1 = 240,
                y1 = 240,
                oldx = 240,
                oldy = 240;
int             key_mode;
int             key_net;
int             step_sum = 0;
int             chessman[LENGTH][LENGTH];
int             depth = 2; /* 搜索的深度 */
int             a = 0,
                b = 0;
int             flag_run;
int             win_flag = 0;

typedef struct five_chess *point;
struct five_chess {
    int             x;
    int             y;
    int             layer;
    double          value;
    double          score;
    int             chess[LENGTH][LENGTH];
    int             record[LENGTH][LENGTH];
} A;
int             stack_deep0 = 0;
point           stack_c[10];
point           close[600];
void
push(point s0)
{
    if (stack_deep0 < 10)
 stack_c[stack_deep0++] = s0;
}
point
top()
{
    if (stack_deep0 > 0)
 return stack_c[stack_deep0 - 1];
    /*else return?*/
}
void
pop()
{
    if (stack_deep0 > 0)
 stack_deep0--;
}
int
is_empty()
{
    if (stack_deep0 != 0)
 return 1;
    else
 return 0;
}
 
/************函数的声明**************/
void            five();
void            show();
int             win_or_not(int x0, int y0, int who,
      int chessman[LENGTH][LENGTH], int a);
void            set_chessman();
void            print_result();
/************评价函数部分************/
double          score_row(int i, int j, int chessman[LENGTH][LENGTH]);
double          score_col(int i, int j, int chessman[LENGTH][LENGTH]);
double          score_diag_45(int i, int j, int chessman[LENGTH][LENGTH]);
double          score_diag_135(int i, int j, int chessman[LENGTH][LENGTH]);
double          total_score(int who_running, int chessman[LENGTH][LENGTH]);
double          score(int chessman[LENGTH][LENGTH]);
int             rowdt(int i, int j, int chessman[LENGTH][LENGTH]);
int             coldt(int i, int j, int chessman[LENGTH][LENGTH]);
int             diadt(int i, int j, int chessman[LENGTH][LENGTH]);
int             vdiadt(int i, int j, int chessman[LENGTH][LENGTH]);
int             can_expand(int i, int j, int chessman[LENGTH][LENGTH]);
void          copy(point s1, point s0);
int
POW(int s, int t)
{
    int             sum = s,
                    i;
    if (t <= 0)
 return 1;
    for (i = 0; i < t; i++)
 sum *= sum;
    return sum;
}

/*
 * 定义computer先手 */
point
expand(point s0)
{
    int             flag;
    int             i,
                    j;
    point           new_chess = (point) malloc(sizeof(struct five_chess));

    if (s0->layer % 2 == 0)
 flag = COMPUTER;
    else
 flag = PLAYER1;

    for (i = 0; i < LENGTH; i++)
 for (j = 0; j < LENGTH; j++) {
     if (s0->record[i][j])                          /*如果有棋子*/
  continue;
     if (can_expand(i, j, s0->chess) == 0)    /*如果有棋子,而且沿水平,树直,左上-右下,右上-左下,四个方向可以扩展*/
  continue;
     s0->record[i][j] = flag;
     new_chess->chess[i][j] = flag;
     new_chess->layer = s0->layer + 1;
     new_chess->x = i;
     new_chess->y = j;
     new_chess->record[i][j] = flag;
     return new_chess;
 }
    /*
     * for(i=5;i<10;i++) for(j=5;j<10;j++){ if(s0->record[i][j]) continue;
     * if(can_expand(i,j,s0->chess)==0) continue; s0->record[i][j]=flag;
     * new_chess->x=i; new_chess->y=j; new_chess->record[i][j]=flag;
     * new_chess->layer=s0->layer+1; new_chess->chess[i][j]=flag ; return
     * new_chess; } for(i=2;i<12;i++) for(j=2;j<12;j++){
     * if(i>4&&i<10&&j>4&&j<10) continue; if(s0->record[i][j]) continue;
     * if(can_expand(i,j,s0->chess)==0) continue; s0->record[i][j]=flag;
     * new_chess->x=i; new_chess->y=j; new_chess->record[i][j]=flag;
     * new_chess->layer=s0->layer+1; new_chess->chess[i][j]=flag; return
     * new_chess;
     * 
     * } for(i=0;i<LENGTH;i++) for(j=0;j<LENGTH;j++){
     * if(i>1&&i<12&&j>1&&j<12) continue; if(s0->record[i][j]) continue;
     * if(can_expand(i,j,s0->chess)==0) continue; s0->record[i][j]=flag;
     * new_chess->chess[i][j]=flag; new_chess->layer=s0->layer+1;
     * new_chess->x=i; new_chess->y=j; new_chess->record[i][j]=flag; return 
     * new_chess; } 
     */
    new_chess->layer = -1;
    return new_chess;
}
 
void
computer()
{
    int             i,
                    j,
                    k,
                    num = 0;
    int             break_now = 0;
    int             break_then = 0;
    int             go_on = 0;
    point         s0 = NULL,
                    s1 = NULL,
                    s2 = NULL,
                    max_chess = NULL;
    point          temps = NULL,
                    s01;
    /*
     * 堆栈的初始化
     */
    stack_deep0 = 0;
    s0 = malloc(sizeof(struct five_chess));
    for (i = 0; i < 600; i++)                           /*为什么是600*/
 close[i] = NULL;                                  /*close是一个point 数组*/
    close[num++] = s0;
    for (i = 0; i < LENGTH; i++)
 for (j = 0; j < LENGTH; j++) {
     s0->chess[i][j] = chessman[i][j];
     s0->record[i][j] = chessman[i][j];
 }
    s0->layer = 0;
    s0->value = -3000000;
    s0->score = -3000000;
    push(s0);
    while (is_empty() != 0) {                /*看是栈否为空*/
 s01 = top();                                   /*如果不是空*/
 s1 = expand(s01);                         /*从栈顶开始展开*/
 close[num++] = s1;
 if (s1->layer == -1) {
     pop();
     continue;
 }
 go_on =
     win_or_not((s1->x + 1) * 30, (s1->y + 1) * 30, 2, s1->chess,
         1);
 if (go_on == 2) {
     a = (s1->x + 1) * 30;
     b = (s1->y + 1) * 30;
     break_then = 1;
     break;
 }
 go_on =
     win_or_not((s1->x + 1) * 30, (s1->y + 1) * 30, 1, s1->chess,
         1);
 if (go_on == 1) {
     a = (s1->x + 1) * 30;
     b = (s1->y + 1) * 30;
     break_then = 1;
     break;
 }
 s1->value = 30000;
 push(s1);
 while (1) {
     s1 = top();
     s2 = expand(s1);
     if (s2->layer == -1) {
  pop();
  if (s1->value > top()->value) {
      top()->value = s1->value;
      max_chess = s1;
  }
  free(s2);
  break;
     }
     s2->score = score(s2->chess);
     temps = top();
     if (s2->score < temps->value)
  temps->value = s2->score;
     free(s2);
 }
    }
    if (break_then == 0) {
 for (i = 0; i < LENGTH; i++) {
     for (j = 0; j < LENGTH; j++)
  if (max_chess->chess[i][j] != chessman[i][j]) {
      a = i * 30 + 30;
      b = j * 30 + 30;
      break_now = 1;
      break;
  }
     if (break_now == 1)
  break;
 }
    }
    for (i = 0; i < 600; i++) {
 if (close[i] == NULL)
     continue;
 free(close[i]);
    }
}
/**********************************************************/
void
main()
{
    int             key;
    int             play_with_who = 1;
    printf("1.Play with human\n2.Play with computer\nPlease choice: ");
    scanf("%d", &play_with_who);
 
    five();                           /*显示棋盘*/
    show();
    if (play_with_who == 1) {      /*人与人玩*/
 while (1) {    /*设置人与人玩的界面*/
     settextstyle(0, 0, 2);
     if ((step_sum + 1) % 2) {
  setcolor(1);
  outtextxy(500, 180, "Player2");
  setcolor(4);
  outtextxy(500, 180, "Player1");
     } else {
  setcolor(1);
  outtextxy(500, 180, "Player1");
  setcolor(10);
  outtextxy(500, 180, "Player2");
     }

     if (bioskey(1))
  /*
   * 按了一次键盘那么就true,执行下面代码,这是bios。h
   */
     {
  key = bioskey(0);
  /*
   * 返回一个键盘值,如没有按键,则一直等待
   */
  switch (key) {
  case ESC:
      exit(0);
  case LEFT:
      if (x1 > 30) {
   x1 -= 30;
   show();      /*显示方框*/
      }
      break;
  case UP:
      if (y1 > 30) {
   y1 -= 30;
   show();
      }
      break;
  case RIGHT:
      if (x1 < 450) {
   x1 += 30;
   show();
      }
      break;
  case DOWN:
      if (y1 < 450) {
   y1 += 30;
   show();
      }
      break;
  case BLANK:                  /*按下空格键后放置棋子*/
      {
   if (chessman[x1 / 30][y1 / 30])
       break;              /*如果当前位置有棋子,不能放置,退出*/
   step_sum++;       /*如果没有棋子,下一步谁走加1*/
   /*
    * P1 设置棋子
    */
   if (step_sum % 2) {
       setcolor(15);    /*画棋子*/
       setfillstyle(SOLID_FILL, 15); /* 封闭图形,进行实体填充*/
       circle(x1, y1, 10);           /*画圆*/
       floodfill(x1, y1, 15);       /*填充圆*/
       chessman[x1 / 30][y1 / 30] = PLAYER1;               /*设置棋盘状态*/
       win_flag = win_or_not(x1, y1, 1, chessman, 0);      /*分析游戏是否结束,谁胜谁败*/
       if (win_flag == 1)
    outtextxy(480, 240, "P1 Win");
       else if (win_flag == 3)
    outtextxy(480, 240, "DOGFALL");
       if (win_flag != 0) {                     /*如果没人胜,游戏继续*/
    while (bioskey(1) == 0);
    closegraph();                   
       }
   } else { /* P2 设置棋子 */
       setcolor(12);                        
       setfillstyle(SOLID_FILL, 12);
       circle(x1, y1, 10);
       floodfill(x1, y1, 12);
       chessman[x1 / 30][y1 / 30] = PLAYER2;
       win_flag = win_or_not(x1, y1, 2, chessman, 0);
       if (win_flag == 2)
    outtextxy(480, 240, "P2 Win");
       else if (win_flag == 3)
    outtextxy(480, 240, "DOGFALL");
       if (win_flag != 0) {
    while (bioskey(1) == 0);
    closegraph();
       }
   }
 
      }
      break;
  }
     }
 }
    } else {
 chessman[7][7] = COMPUTER;             /*人和电脑玩,电脑先走一步*/           
 setcolor(12);
 setfillstyle(SOLID_FILL, 12);
 circle(240, 240, 10);
 floodfill(240, 240, 12);
 flag_run = 0;                    /*有什么用?*/
 step_sum++;                   /*下一步谁走?*/
 while (1) {
     while (1) {
  if (flag_run == 1)
      break;
  if (bioskey(1)) {
      key = bioskey(0);
      /*
       * 返回一个键盘值,如没有按键,则一直等待
       */
      switch (key) {
      case ESC:
   exit(0);
      case LEFT:
   if (x1 > 30) {
       x1 -= 30;
       show();
   }
   break;
      case UP:
   if (y1 > 30) {
       y1 -= 30;
       show();
   }
   break;
      case RIGHT:
   if (x1 < 450) {
       x1 += 30;
       show();
   }
   break;
      case DOWN:
   if (y1 < 450) {
       y1 += 30;
       show();
   }
   break;
      case BLANK:
   {
       if (chessman[x1 / 30 - 1][y1 / 30 - 1])
    break;                                                          /*有棋子了不走*/
       setcolor(15);
       setfillstyle(SOLID_FILL, 15); /* 封闭图形,进行实体填充 
         */
       circle(x1, y1, 10);
       floodfill(x1, y1, 15);                              /*画棋子*/
       chessman[x1 / 30 - 1][y1 / 30 - 1] = PLAYER1;
       flag_run = 1;                                  /*有什么用?*/
       step_sum++;                                 /*下一步谁走*/
       win_flag = win_or_not(x1, y1, 1, chessman, 0);   /*谁胜谁负*/
       if (win_flag == 1)
    outtextxy(480, 240, "P1 Win");
       else if (win_flag == 3)
    outtextxy(480, 240, "DOGFALL");
       if (win_flag != 0) {
    while (bioskey(1) == 0);                                 /*没有人胜则继续等待下棋*/
    closegraph();
       }
   }
      }  /* switch */
  }
     }
     computer();                                            /*调用智能体*/
     /*
      * a,b存放的是现在电脑准备下的位置
      * 返回一个a,b的结构体不是更好,用全局变量不爽啊
      * struct {
      *          int a;
      *         int b;
      *  }
      */
     setcolor(12);
     setfillstyle(SOLID_FILL, 12);
     circle(a, b, 10);
     floodfill(a, b, 12);
     chessman[a / 30 - 1][b / 30 - 1] = COMPUTER;
     flag_run = 0;
     step_sum++;
     win_flag = win_or_not(a, b, 2, chessman, 0);
     if (win_flag == 2)
  outtextxy(480, 240, "ComputerWin");
     else if (win_flag == 3)
  outtextxy(480, 240, "DOGFALL");
     if (win_flag != 0) {
  while (bioskey(1) == 0);
  closegraph();
     }
 
 
 }
    }
}
void
five()
{
    int             i,
                    j;
    /*
     * 画棋盘的过程
     */
    int             gdriver = DETECT,
                    gmode;
    registerbgidriver(EGAVGA_driver);
    initgraph(&gdriver, &gmode, " ");
    /*
     * 对显示适配器进行配置
     */
    setbkcolor(1);
    for (i = 0; i < 30; i++) {
 setcolor((i >= 2) ? 9 : i);
 rectangle(i, i, 479 - i, 479 - i); /* 画矩形边框 */
    }
    /*
     * 画棋盘
     */
    for (i = 1; i < 14; i++)
 for (j = 1; j < 14; j++) {
     setcolor(14);
     line(30 + 30 * i, 30, 30 + 30 * i, 449);
     line(30, 30 + 30 * i, 449, 30 + 30 * i);
 }
    /*
     * 画整个图的边框
     */
    for (i = 0; i < 15; i++) {
 setcolor(i);
 rectangle(i, i, 640 - i, 480 - i);
 line(480 - i, 15, 480 - i, 465);
    }
    /*
     * 输出屏幕右侧的信息
     */
    setcolor(4);
    settextstyle(0, 0, 2);
    outtextxy(500, 45, "GOBANG");
    setcolor(10);
    settextstyle(0, 0, 1);
    outtextxy(500, 90, "Designed By");
    outtextxy(514, 118, "Ye Binbin");
    outtextxy(480, 140, "from class A of CS");

}
/*
 * 移动光标
 */
void
show()
{
    setcolor(1);
    if (oldx < 450) {
 if (oldy > 30)
     line(oldx + 7, oldy - 15, oldx + 15, oldy - 15);
 if (oldy > 30)
     line(oldx + 15, oldy - 15, oldx + 15, oldy - 7);
 if (oldy < 450)
     line(oldx + 15, oldy + 7, oldx + 15, oldy + 15);
 if (oldy < 450)
     line(oldx + 15, oldy + 15, oldx + 7, oldy + 15);
    }
    if (oldx > 30) {
 if (oldy < 450)
     line(oldx - 7, oldy + 15, oldx - 15, oldy + 15);
 if (oldy < 450)
     line(oldx - 15, oldy + 15, oldx - 15, oldy + 7);
 if (oldy > 30)
     line(oldx - 15, oldy - 7, oldx - 15, oldy - 15);
 if (oldy > 30)
     line(oldx - 15, oldy - 15, oldx - 7, oldy - 15);
    }
    setcolor(12);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -