diff --git a/README.md b/README.md index 9222850..bf89673 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ ss1_TicTacToeEx =============== スキルゼミ第1回 拡張○×ゲーム +サブ用 更新履歴 - 2016.10.28 ver 1.0 diff --git a/TicTacToeEx/T3EBoard.cpp b/TicTacToeEx/T3EBoard.cpp index fda9f09..40da3fe 100644 --- a/TicTacToeEx/T3EBoard.cpp +++ b/TicTacToeEx/T3EBoard.cpp @@ -68,113 +68,92 @@ // �߂�l�F�R�}��łꏊ int T3EBoard::CPU() { + if (m_Turn == 1 && m_NextPlayer == PLAYER1)return 1; + int place = 0; - int i[11],j; - int tempPlace[11]; - int ZeroCount=0,ZeroCount2=0; - int ImageBoard[BOARD_SIZE], ImageTurn,ImageNextPlayer,Me; - //���s�Ǘ��z�� - int row[11], col[11]; - int check[11]; - int sign[2] = { STONE1, STONE2 }; + int NextBoard[BOARD_SIZE]; + int best; + int val; - - //���� - ImageTurn = m_Turn; - ImageNextPlayer = m_NextPlayer; - printf("ImageNext = %d\n", ImageNextPlayer); - //�����͐��̐�,����͕��̐��ŕ��� - if (ImageNextPlayer == PLAYER1) { - printf("���͐��\n"); - for (i[0] = 0;i[0] < BOARD_SIZE;i[0]++) { - ImageBoard[i[0]] = m_Board[i[0]]; + //��莞 + if (m_NextPlayer == PLAYER1) { + best = INT_MIN; + //��肸�‘�����l�݂ɓ����邩���o + for (int i = 0; i < BOARD_SIZE; i++) { + if (m_Board[i] == 0) { + //���̋ǖʂ��i�[ + for (int j = 0; j < BOARD_SIZE; j++) { + NextBoard[j] = m_Board[j]; + } + SetStone(NextBoard, i, m_NextPlayer, m_Turn); + //�]���l���Z�o + val = Minmax(NextBoard, 1 - m_NextPlayer, m_Turn, 12); + //���̏ꍇ�ő�l�����߂� + if (best < val) { + best = val; + place = i; + } + //�l�݂ɓ�����place�����‚��������ɂ���place�Ԃ� + if (best == 1) { + std::cout << "CPU => " << place << std::endl; + return place; + } + } } + std::cout << "CPU => " << place << std::endl; + return place; + } + + // ��莞 else { - printf("���͌��\n"); - for (i[0] = 0;i[0] < BOARD_SIZE;i[0]++) { - ImageBoard[i[0]] = (-1)*m_Board[i[0]]; + best = INT_MAX; + //��肸�‘�����l�݂ɓ����邩���o + for (int i = 0; i < BOARD_SIZE; i++) { + if (m_Board[i] == 0) { + //���̋ǖʂ��i�[ + for (int j = 0; j < BOARD_SIZE; j++) { + NextBoard[j] = m_Board[j]; + } + SetStone(NextBoard, i, m_NextPlayer, m_Turn); + //�]���l���Z�o + val = Minmax(NextBoard, 1 - m_NextPlayer, m_Turn+1, 12); + //���̏ꍇ�ŏ��l�����߂� + if (best > val) { + best = val; + place = i; + } + //�l�݂ɓ�����place�����‚��������ɂ���place�Ԃ� + if (best == -1) { + std::cout << "CPU => " << place << std::endl; + return place; + } + } } - } - - - //�Տ�̉����Ȃ��ꏊ�𐔂���B - for (i[0] = 0;i[0] < BOARD_SIZE;i[0]++) { - if (ImageBoard[i[0]] == 0)ZeroCount++; - } - - //printf("ZERO=%d\n", ZeroCount); - - //Minmax�@�̋L�q - //���݂̃^�[���S�ʂ莎��for depth=0 - for (i[0] = 0;i[0] < BOARD_SIZE;i[0]++) { - //printf("i = %d\n",i[0]); - //�����u���ĂȂ��ꏊ�����‚��� - if (ImageBoard[i[0]] == 0) { - //SetStone�̋L�q�P - ImageBoard[i[0]] = ImageTurn; - tempPlace[0] = i[0]; - - // �Â��R�}������ - if (ImageTurn > MAX_PIECE_ON_BOARD) { - int deleting = (ImageTurn - MAX_PIECE_ON_BOARD); - for (int i = 0; i < BOARD_SIZE; i++) { - if (ImageBoard[i] == deleting) ImageBoard[i] = 0; + //����̃~�X��U�����ԉ҂�1 + if (best == 1) { + for (int i = 0; i < BOARD_SIZE; i++) { + if (m_Board[i] == 0) { + for (int j = 0; j < BOARD_SIZE; j++) { + NextBoard[j] = m_Board[j]; + } + SetStone(NextBoard, i, PLAYER1, m_Turn + 1); + if (CheckWin(NextBoard) == 1)return i; } } - - //���Ă�`�����X�������珟�� - // �΂ߕ���1 - for (row[0] = 0, check[0] = 0; row[0] < BOARD_HEIGHT; row[0]++) { - if (ImageBoard[row[0] * BOARD_WIDTH + row[0]] > 0) check[0]++; - } - if (check[0] == 3) { - printf("naname1\n");return i[0]; - } - - // �΂ߕ���2 - for (row[0] = 0, check[0] = 0; row[0] < BOARD_HEIGHT; row[0]++) { - if (ImageBoard[row[0] * BOARD_WIDTH + (BOARD_HEIGHT - 1 - row[0])] > 0) check[0]++; - } - if (check[0] == 3) { - printf("naname2\n");return i[0]; - } - - // ������ - for (row[0] = 0; row[0] < BOARD_HEIGHT; row[0]++) { - for (col[0] = 0, check[0] = 0; col[0] < BOARD_WIDTH; col[0]++) { - if (ImageBoard[row[0] * BOARD_WIDTH + col[0]] > 0) check[0]++; - } - if (check[0] == 3) { - printf("yoko\n");return i[0]; - } - - } - - - // �c���� - for (col[0] = 0; col[0] < BOARD_WIDTH; col[0]++) { - for (row[0] = 0, check[0] = 0; row[0] < BOARD_HEIGHT; row[0]++) { - if (ImageBoard[row[0] * BOARD_WIDTH + col[0]] > 0) check[0]++; - } - if (check[0] == 3) { - printf("tate\n");return i[0]; - } - } - - - //����̎�� depth=1 - ImageTurn++; - for (i[1] = 0;i[1] < BOARD_SIZE;i[1]++) { - if (ImageBoard[i[1]] == 0) { - - } - } - //������Ԃɖ߂� - ImageBoard[tempPlace[0]] = 0; - ImageTurn = m_Turn; - ImageNextPlayer = m_Turn; } + + //����̃~�X��U�����ԉ҂��Q + if (m_Turn == 1) { + if (m_Board[1] == 1)return 8; + if (m_Board[3] == 1)return 8; + if (m_Board[5] == 1)return 0; + if (m_Board[7] == 1)return 0; + + } + + std::cout << "CPU => " << place << std::endl; + return place; } do { @@ -185,21 +164,223 @@ return place; } + +//�ǂ̔Ֆʂ������Ɉ�ԑ傫���]���������炷���m�F�B +//����:int node �ǖ�, in turn ���, int turn �^�[����,int depth ��ǂ݂̐[��,int state ��� +//�߂�l�F�]���l +int T3EBoard::Minmax(int *node, int NextPlayer, int turn, int depth) +{ + + //�t�̏ꍇ�]���l��Ԃ� + if (depth == 0) { + return this->CheckWin(node); + } + + //���łɏ������‚��Ă���ꍇ�t�Ƃ݂Ȃ��ĕ]���l��Ԃ� + if(CheckWin(node) !=0){ + return this->CheckWin(node); + } + + + int NextBoards[BOARD_SIZE*BOARD_SIZE]; + int NextBoard[BOARD_SIZE]; + int NextNode; + int NextNextPlayer = 1 - NextPlayer; + int NextTurn = turn; + int temp[BOARD_SIZE]; + int k = 0; //���̋ǖʊi�[�p�ϐ� + int val; + + if (NextNextPlayer == PLAYER1)NextTurn++; + + //�m�[�h����i�߂� + //���̉”\�萔�𐔂��� + NextNode = this->count_zero(node); + //�΂�u�����ǖʂ�S�Ċi�[ + for (int i = 0;i < BOARD_SIZE;i++) { + if (node[i] == 0) { + for (int l = 0; l < BOARD_SIZE; l++) { + temp[l] = node[l]; + } + + this->SetStone(temp, i, NextPlayer, turn); + for (int j = 0;j < BOARD_SIZE;j++) { + NextBoards[k] = temp[j]; + k++; + } + } + } + + + k = 0; + int best1 = INT_MIN; + int best2 = INT_MAX; + for (int i = 0;i < NextNode;i++) { + for (int j = 0;j < BOARD_SIZE;j++) { + NextBoard[j] = NextBoards[k]; + k++; + } + + if (CheckWin(NextBoard) != 0) { + val = this->Minmax(NextBoard, NextNextPlayer, NextTurn, (depth - 1)); + } + else{ + val = this->Minmax(NextBoard, NextNextPlayer, NextTurn, (depth - 1)); + } + if (NextPlayer == PLAYER1 && best1 < val) { + best1 = val; + } + if (NextPlayer == PLAYER2 && val < best2) { + best2 = val; + } + } + + if(NextPlayer == PLAYER1){ + return best1; + } + + if (NextPlayer == PLAYER2) { + return best2; + } +} + +//�z�񂲂Ƃɂ�鏟�s���� +//����:int *Board�@�ǖ� +//�߂�l�G0 ������ 1(PLAYER1) ��菟�� -1(PLAYER2) ��菟�� +int T3EBoard::CheckWin(int *Board) +{ + int row, col; + bool check; + int sign[2] = { STONE1, STONE2 }; + + // �v���C���[���ɔ��� + for (int player = PLAYER1; player <= PLAYER2; player++) { + // �΂ߕ���1 + for (row = 0, check = true; row < BOARD_HEIGHT; row++) { + if (Board[row * BOARD_WIDTH + row] * sign[player] <= 0) check = false; + } + if (check) { + if (player == PLAYER1)return 1; + return -1; + } + + // �΂ߕ���2 + for (row = 0, check = true; row < BOARD_HEIGHT; row++) { + if (Board[row * BOARD_WIDTH + (BOARD_HEIGHT - 1 - row)] * sign[player] <= 0) check = false; + } + if (check) { + if (player == PLAYER1)return 1; + return -1; + } + + // ������ + for (row = 0; row < BOARD_HEIGHT; row++) { + for (col = 0, check = true; col < BOARD_WIDTH; col++) { + if (Board[row * BOARD_WIDTH + col] * sign[player] <= 0) check = false; + } + if (check) { + if (player == PLAYER1)return 1; + return -1; + } + } + + // �c���� + for (col = 0; col < BOARD_WIDTH; col++) { + for (row = 0, check = true; row < BOARD_HEIGHT; row++) { + if (Board[row * BOARD_WIDTH + col] * sign[player] <= 0) check = false; + } + if (check) { + if (player == PLAYER1)return 1; + return -1; + } + } + } + + return 0; + +} + +// �����z��̉”\�萔���Z�o +// �����Fint *Board ��� +//�߂�l�F�”\�萔 +int T3EBoard::count_zero(int *Board) +{ + int Count = 0; + + for (int i = 0; i < BOARD_SIZE; i++) { + if (Board[i] == 0)Count++; + } + + return Count; +} + + +//�΂�u�� +//�����Fint *Board �ǖ�, int place�@�u���ꏊ, int NextPlayer ���u���l, int turn �^�[���� +void T3EBoard::SetStone(int *Board, int place, int NextPlayer, int Turn) { + int sign = NextPlayer == PLAYER1 ? STONE1 : STONE2; + Board[place] = Turn * sign; + + // �Â��R�}������ + if (Turn > MAX_PIECE_ON_BOARD) { + int deleting = (Turn - MAX_PIECE_ON_BOARD) * sign; + for (int i = 0; i < BOARD_SIZE; i++) { + if (Board[i] == deleting) Board[i] = 0; + } + } +} + +//�z��̔Ԃ�\�� +void T3EBoard::ShowBoard(int *Board) +{ + for (int i = 0; i < BOARD_SIZE; i++) { + std::cout << (Board[i] == 0 ? "�@" : + (Board[i] > 0 ? "��" : "�~")); + if (i % BOARD_WIDTH < BOARD_WIDTH - 1) { + std::cout << "��"; + } + else { + std::cout << std::endl; + if (i < BOARD_SIZE - 1) std::cout << "����������" << std::endl; + } + } +} + + // �l�Ԃ̎�� // �߂�l�F�R�}��łꏊ int T3EBoard::Human() { + if (m_Turn == 1 && m_NextPlayer == PLAYER1)return 1; + int place = 0; - while(1) { + int NextBoard[BOARD_SIZE]; + int NextNextPlayer; + int NextTurn = m_Turn; + + NextNextPlayer = 1 - m_NextPlayer; + if (NextNextPlayer == PLAYER1)NextTurn++; + + for (int i = 0;i < BOARD_SIZE;i++) { + if (m_Board[i] == 0) { + for (int j = 0;j < BOARD_SIZE;j++) { + NextBoard[j] = m_Board[j]; + } + SetStone(NextBoard, i, m_NextPlayer, m_Turn); + printf("�u���ꏊ[%d]�̕]���l��[%d]�ł��B\n", i, Minmax(NextBoard, NextNextPlayer, NextTurn, 12)); + } + } + + + while (1) { std::cout << "0:���� 1:�� 2:�E�� 3:�� 4:���� 5:�E 6:���� 7:�� 8:�E��" << std::endl << "�ǂ��ɑł��܂����H "; std::cin >> place; if (place >= 0 && place < BOARD_SIZE) { if (m_Board[place] == 0) break; } + return place; } - - return place; } // �ՂɃR�}��u�� diff --git a/TicTacToeEx/T3EBoard.h b/TicTacToeEx/T3EBoard.h index d05eecb..73e448b 100644 --- a/TicTacToeEx/T3EBoard.h +++ b/TicTacToeEx/T3EBoard.h @@ -22,6 +22,11 @@ void ShowBoard(); // �Օ\�� void SetStone(int place); // �R�}��u�� int CPU(); // CPU�̎v�l + int Minmax(int *node, int NextPlayer, int turn, int depth);//Minmax�@�̎��{ + int CheckWin(int *Board); // �󋵂ɂ�鏟�s�`�F�b�N + int count_zero(int *Board); // �����z��̉”\�萔���Z�o + void SetStone(int *Board, int place, int NextPlayer, int Turn); //�R�}��u�� + void ShowBoard(int *Board); //�ӕ\�� int Human(); // �l�Ԃ̎�� int CheckWin(); // �������� public: