LoginSignup
3
3

More than 5 years have passed since last update.

Connect Four(C言語で4目並べ)

Posted at

よくある4目並べです。
かなり幼稚なCPUのアルゴリズムなのでもっと強くしたい。
先攻はCPUです。
20ターンCPUが持ちこたえたら僕の勝ち。


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

void  displayMatrix (int matrix[7][6])
{
    int   row, column;

    for ( column = 5;  column >= 0;  --column) {
        for ( row = 0;  row < 7;  ++row )
            printf ("%5i", matrix[row][column]);
        printf ("\n");
    }
}

//
// the function that checks there are vertical connection or not
// same algorithm for vertical, horizontal and diagonal
// amount = how many connections
//
int vertical(int cpu, int player, int amount, int table[7][6])
{
  for (int i = 0; i < 7; ++i)
  {
    cpu = 0;
    player = 0;
    for (int h = 0; h < 6; ++h)
    {
      if(cpu == amount)
      {
        return 1;
      }
      else if(player == amount)
      {
        return 2;
      }

      if(table[i][h] == 1){
      cpu += 1;
      player = 0;
      }
      else if(table[i][h] == 2){
        player += 1;
        cpu = 0;
      }
      else{
        cpu = 0;
        player = 0;
      }
    }
  }

  return 0;
}

int horizontal(int cpu, int player, int amount, int table[7][6])
{
  for (int h = 0; h < 6; ++h)
  {
    cpu = 0;
    player = 0;
    for (int i = 0; i < 7; ++i)
    {
      if(cpu == amount)
      {
        return 1;
      }
      else if(player == amount)
      {
        return 2;
      }

      if(table[i][h] == 1){
        cpu += 1;
        player = 0;
      }
      else if(table[i][h] == 2){
        player += 1;
        cpu = 0;
      }
      else{
        cpu = 0;
        player = 0;
      }
    }
  }

  return 0;
}

int diagonal(int cpu, int player, int amount, int table[7][6])
{
  for (int i = 0; i < 7; ++i)
  {
    cpu = 0;
    player = 0;
    for (int h = 0, k = 0; h < 7, k < 6; ++h, ++k)
    {
      int point = table[i + h][k];
      if(cpu == amount)
      {
        return 1;
      }
      else if(player == amount)
      {
        return 2;
      }

      if(point == 1){
        ++cpu;
        player = 0;
      }
      else if(point == 2){
        ++player;
        cpu = 0;
      }
      else{
        cpu = 0;
        player = 0;
      }
    }
  }

  cpu = 0;
  player = 0;

  for (int i = 6; i >= 0; --i)
  {
    cpu = 0;
    player = 0;
    for (int h = 0, k = 0; h < 7, k < 6; ++h, ++k)
    {
      int point = table[i - h][k];
      if(cpu == amount)
      {
        return 1;
      }
      else if(player == amount)
      {
        return 2;
      }

      if(point == 1){
        ++cpu;
        player = 0;
      }
      else if(point == 2){
        ++player;
        cpu = 0;
      }
      else{
        cpu = 0;
        player = 0;
      }
    }
  }

  for (int i = 1; i < 3; ++i)
  {
    cpu = 0;
    player = 0;
    for (int h = 0, k = 0; h < 5, k < 6; ++h, ++k)
    {
      int point = table[h][i + k];
      if(cpu == amount)
      {
        return 1;
      }
      else if(player == amount)
      {
        return 2;
      }

      if(point == 1){
        ++cpu;
        player = 0;
      }
      else if(point == 2){
        ++player;
        cpu = 0;
      }
      else{
        cpu = 0;
        player = 0;
      }
    }
  }

  for (int i = 6; i >= 0; --i)
  {
    cpu = 0;
    player = 0;
    for (int h = 0, k = 1; h < 7, k < 6; ++h, ++k)
    {
      int point = table[i - h][k];
      if(cpu == amount)
      {
        return 1;
      }
      else if(player == amount)
      {
        return 2;
      }

      if(point == 1){
        ++cpu;
        player = 0;
      }
      else if(point == 2){
        ++player;
        cpu = 0;
      }
      else{
        cpu = 0;
        player = 0;
      }
    }
  }

  return 0;
}

// function for just create random number between min and max
int random_number(int min, int max)
{
  return min + (int)(rand()*(max - min + 1.0) / (1.0 + RAND_MAX));
}

// checks there are crucial hand or not
int check_mate(int number, int column_number, int table[7][6], int side)
{
  // checking cpu's hands
  for (number = 0; number < 7; ++number)
  {
    column_number = 7;
    for (int i = 0; i < 6; ++i){
      if (table[number][i] == 0){
        table[number][i] = side;
        column_number = i;
        break;
      }
    }
    if(column_number != 7){
      if (vertical(0, 0, 4, table) == side || horizontal(0, 0, 4, table) == side || diagonal(0, 0, 4, table) == side){
        if (side == 2)
        {
          table[number][column_number] = 1;
        }
        return 1;
      }
      else{
        table[number][column_number] = 0;
      }
    }
  }
  return 0;
}

int main(int argc, char const *argv[])
{
  void displayMatrix(int matrix[7][6]);
  int vertical(int cpu, int player, int amount, int table[7][6]);
  int horizontal(int cpu, int player, int amount, int table[7][6]);
  int diagonal(int cpu, int player, int amount, int table[7][6]);
  int check_mate(int cpu_number, int column_number, int table[7][6], int side);
  int connect[7][6] =
          {
              { 0, 0, 0, 0, 0, 0 },
              { 0, 0, 0, 0, 0, 0 },
              { 0, 0, 0, 0, 0, 0 },
              { 1, 0, 0, 0, 0, 0 },
              { 0, 0, 0, 0, 0, 0 },
              { 0, 0, 0, 0, 0, 0 },
              { 0, 0, 0, 0, 0, 0 },
          };
  int count = 0, player_number = 0, cpu_number = 0, column_number = 0;

  printf("    ∧,,∧\n   ( 'ω' )つ Game Start!!!\n   (m9 \ \n     \   \\n        ) ) \\n      // \ \\n     (_)   (_)\n");
  // game start
  while(true){
    printf("count: %i\n", count);
    printf("-------------------------------------\n");
    printf("    1    2    3    4    5    6    7\n");
    printf("-------------------------------------\n");
    displayMatrix (connect);

    // check
    int cpu = 0, player = 0;
    if (vertical(cpu, player, 4, connect) == 1 || horizontal(cpu, player, 4, connect) == 1 || diagonal(cpu, player, 4, connect) == 1){
      printf("         nn\n      (´・ω・)\n    _|  ⊃/(___\n  /  └-(____/\n   ̄ ̄ ̄ ̄ ̄ ̄ ̄\nYou LOSE....");
      return 0;
    }
    else if(vertical(cpu, player, 4, connect) == 2 || horizontal(cpu, player, 4, connect) == 2 || diagonal(cpu, player, 4, connect) == 2)
    {
      printf("      ☆ *  .   ☆ \n    ☆  . ∧_∧  n  * ☆ \n  kt━━━( ・∀・)/ . ━━━!!\n     . ⊂     ノ* ☆ \n   ☆ * (つ ノ .☆ \n       (ノ\n     You WIN!!!!\n");
      return 0;
    }

    // play
    // 1: put 0 into number
    // 2: check cpu has check mate move or not
    // 3: check player has check mate move
    // 4: loop it until 6
    // 5: if there are no check mate move, put random number into number
    if (count % 2 == 1)
    {
      // cpu's turn
      int cpu = 0, player = 0;

      if (check_mate(0, 0, connect, 1)){
        printf("are you serious?\n");
      }
      else if(check_mate(0, 0, connect, 2)){
        printf("close!\n");
      }
      else{
        cpu_number = random_number(0, 6);
        for (int i = 0; i < 6; ++i){
          if (connect[cpu_number][i] == 0){
            connect[cpu_number][i] = 1;
            break;
          }
        }
      }
    }
    else{
      // player's turn
        printf("Your Turn\n");
        printf("put in your peg\n");
        printf("Press (only) 1 ~ 7\n");
        scanf  ("%i", &player_number);
        for (int i = 0; i < 6; ++i){
          if (connect[player_number - 1][i] == 0){
            connect[player_number - 1][i] = 2;
            break;
          }
        }
    }
    count += 1;
  }

  return 0;
}

冬休み入ったらもっとかっこいいコードに修正しよ

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3