File indexing completed on 2024-11-24 03:43:17
0001 /******************************************************************* 0002 * 0003 * Copyright 2009 Pelladi Gabor <pelladigabor@gmail.com> 0004 * 0005 * Bovo is free software; you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation; either version 2, or (at your option) 0008 * any later version. 0009 * 0010 * Bovo is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with Bovo; see the file COPYING. If not, write to 0017 * the Free Software Foundation, 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 * 0020 ********************************************************************/ 0021 0022 #ifndef BOVO_STANDING_H 0023 #define BOVO_STANDING_H 0024 0025 #include <QList> 0026 0027 #include "ai_interface.h" 0028 0029 #include <list> 0030 0031 // a mark on the table 0032 using mark_T = unsigned char; 0033 // occurrences of a certain position 0034 using count_T = unsigned char; 0035 // small index for a constant array 0036 using index_T = unsigned char; 0037 0038 // table symbols indexed with player number 0039 const mark_T mark[] = {'o', 'x', '!', '\0'}; 0040 0041 // the game table 0042 typedef mark_T table_T[max_table_size][max_table_size]; 0043 // the value of the fields for the two players for the next step 0044 typedef count_T suggest_T[2][max_table_size][max_table_size]; 0045 0046 // heuristic type 0047 using heur_T = short; 0048 0049 // type for total number of marks on the table 0050 using stepCount_T = unsigned short; 0051 0052 // maximal and minimal value of the heuristic function 0053 const heur_T MaxHeur = 10000; 0054 const heur_T MinHeur = -MaxHeur; 0055 // one hundredth of the maximum value 0056 const heur_T HeurPercent = MaxHeur / 100; 0057 // values above WinTreshold mean winning positions 0058 const heur_T WinTreshold = 98 * HeurPercent; 0059 // heuristic value decreases by this amount times the current depth 0060 const heur_T depth_decay = 5; 0061 // if the seed is too big, do not use the hash 0062 const heur_T normal_heur_seed = 2; 0063 0064 // number of categories used in the heuristic function 0065 const index_T heurLevels = 6; 0066 // occurrence of patterns for the two players 0067 typedef count_T PatternCount[2][heurLevels]; 0068 0069 // a row, column or diagonal of the table 0070 using sample_T = QList<mark_T>; 0071 // interesting fields for the two players for the next step 0072 using suggestions_T = std::list<Field>; 0073 0074 class Standing; 0075 // callback function to convert a position of the sample into coordinates, and update suggestions accordingly 0076 using posf_T = void (Standing::*)(pos_T, int, count_T, count_T); 0077 0078 // game state class 0079 class Standing 0080 { 0081 public: 0082 // the current game table 0083 table_T table; 0084 // the size of the table 0085 pos_T table_size_x, table_size_y; 0086 // the heuristic value of the standing 0087 heur_T hval; 0088 // the random seed added to the heuristic value 0089 heur_T heur_seed; 0090 // true if a player has won 0091 bool target; 0092 // total number of marks on the table 0093 stepCount_T stepCount; 0094 // the player on turn 0095 index_T current; 0096 // the move that created this standing 0097 pos_T lastx, lasty; 0098 // following move suggestion values 0099 suggest_T suggest; 0100 0101 // calculate constant values for refresh 0102 static void initRefresh(); 0103 0104 // new game 0105 Standing(pos_T _table_size_x, pos_T _table_size_y); 0106 // copy a game state 0107 Standing(const Standing &other) = default; 0108 Standing &operator=(const Standing &other) = default; 0109 0110 // make a step 0111 void step(pos_T x, pos_T y); 0112 // mark a field a "wall", where neither player can step 0113 void step_server(pos_T x, pos_T y); 0114 0115 // get the interesting fields for the two players for the next step 0116 void getSuggestions(suggestions_T &suggestions); 0117 0118 private: 0119 // global occurrence of patterns 0120 PatternCount matchCount; 0121 // occurrence of patterns in each row 0122 PatternCount matchCountRow[max_table_size]; 0123 // occurrence of patterns in each column 0124 PatternCount matchCountColumn[max_table_size]; 0125 // occurrence of patterns in each diagonal, where the sum of coordinates is constant 0126 PatternCount matchCountDiagonalSum[2 * max_table_size - 1]; 0127 // occurrence of patterns in each diagonal, where the difference of coordinates is constant 0128 PatternCount matchCountDiagonalDiff[2 * max_table_size - 1]; 0129 0130 // interesting field values coming from row patterns 0131 suggest_T suggestRow; 0132 // interesting field values coming from column patterns 0133 suggest_T suggestColumn; 0134 // interesting field values coming from diagonal patterns, where the sum of coordinates is constant 0135 suggest_T suggestDiagonalSum; 0136 // interesting field values coming from diagonal patterns, where the difference of coordinates is constant 0137 suggest_T suggestDiagonalDiff; 0138 0139 // callback function to convert a position of the row sample into coordinates, and update suggestions accordingly 0140 void posfRow(pos_T pos, int y, count_T value0, count_T value1); 0141 // callback function to convert a position of the column sample into coordinates, and update suggestions accordingly 0142 void posfColumn(pos_T pos, int x, count_T value0, count_T value1); 0143 // callback function to convert a position of the sum diagonal sample into coordinates, and update suggestions accordingly 0144 void posfDiagonalSum(pos_T pos, int sum, count_T value0, count_T value1); 0145 // callback function to convert a position of the diff diagonal sample into coordinates, and update suggestions accordingly 0146 void posfDiagonalDiff(pos_T pos, int diff, count_T value0, count_T value1); 0147 0148 // calculate heuristic value 0149 void evaluate(); 0150 0151 // count occurrences of the patterns 0152 void countMatches(); 0153 // refresh matchCount and suggest variables after a step 0154 // this function consumes 90% of the thinking time 0155 void refresh(sample_T &sample, PatternCount &local, int inv, posf_T posf); 0156 // process pattern occurrences 0157 void decide(); 0158 }; 0159 0160 #endif // BOVO_STANDING_H