File indexing completed on 2024-09-29 06:37:50
0001 /* 0002 This file is part of the KDE games kwin4 program 0003 SPDX-FileCopyrightText: 2006 Martin Heni <kde@heni-online.de> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "aiboard.h" 0009 0010 // own 0011 #include "kfourinline_debug.h" 0012 // Std 0013 #include <cstdio> 0014 0015 // Construct a board object 0016 AIBoard::AIBoard() 0017 { 0018 } 0019 0020 // Construct a board object from a given game field. 0021 AIBoard::AIBoard(uchar current, const char field[][7]) 0022 { 0023 fromField(current, false, field); 0024 } 0025 0026 // Compare two boards 0027 bool AIBoard::operator==(const AIBoard &other) const 0028 { 0029 if (mCurrent != other.mCurrent) 0030 return false; 0031 for (int i = 0; i < 6; i++) { 0032 if (mBoard[i] != other.mBoard[i]) 0033 return false; 0034 } 0035 return true; 0036 } 0037 0038 // Create a board from a given game field. Support mirroring the field. 0039 void AIBoard::fromField(uchar current, bool mirror, const char field[][7]) 0040 { 0041 // Store current player 0042 mCurrent = current; 0043 0044 // Loop rows 0045 for (int y = 0; y <= 5; y++) { 0046 ushort tmp = 0; 0047 // Loop columns 0048 for (int x = 0; x <= 6; x++) { 0049 tmp = tmp << 2; 0050 // Mirror board? 0051 if (mirror) { 0052 if (field[y][6 - x] == Yellow) 0053 tmp |= 1; 0054 else if (field[y][6 - x] == Red) 0055 tmp |= 2; 0056 // else tmp |= 0; 0057 } else { 0058 if (field[y][x] == Yellow) 0059 tmp |= 1; 0060 else if (field[y][x] == Red) 0061 tmp |= 2; 0062 // else tmp |= 0; 0063 } 0064 } 0065 mBoard[y] = tmp; 0066 } 0067 } 0068 0069 // Retrieve a mirrored board. 0070 AIBoard AIBoard::mirror() const 0071 { 0072 AIBoard other; 0073 other.mCurrent = mCurrent; 0074 0075 // Loop rows 0076 for (int y = 0; y <= 5; y++) { 0077 ushort tmp = mBoard[y]; 0078 ushort ntmp = 0; 0079 // Loop columns 0080 for (int x = 0; x <= 6; x++) { 0081 ntmp = ntmp << 2; 0082 ntmp |= (tmp >> (x << 1)) & 3; 0083 } 0084 other.mBoard[y] = ntmp; 0085 } 0086 return other; 0087 } 0088 0089 // Debug function to output the board. 0090 void AIBoard::print() const 0091 { 0092 fprintf(stderr, " AIBOARD ======== COLOR %d ========\n", mCurrent); 0093 for (int i = 5; i >= 0; i--) { 0094 ushort tmp = mBoard[i]; 0095 fprintf(stderr, " Row %d: [%04x]", i, tmp); 0096 for (int x = 6; x >= 0; x--) { 0097 if (((tmp >> (x * 2)) & 3) == 1) 0098 fprintf(stderr, " 1 "); 0099 else if (((tmp >> (x * 2) & 3)) == 2) 0100 fprintf(stderr, " 2 "); 0101 else 0102 fprintf(stderr, " 0 "); 0103 } 0104 fprintf(stderr, "\n"); 0105 } 0106 fflush(stderr); 0107 } 0108 0109 // Stream the board 0110 QDataStream &operator<<(QDataStream &s, const AIBoard &board) 0111 { 0112 s << (qint8)board.mCurrent; 0113 for (int i = 0; i < 6; i++) 0114 s << (qint16)board.mBoard[i]; 0115 return s; 0116 } 0117 0118 // Stream the board 0119 QDataStream &operator>>(QDataStream &s, AIBoard &board) 0120 { 0121 qint8 tmp8; 0122 qint16 tmp16; 0123 s >> tmp8; 0124 board.mCurrent = tmp8; 0125 for (int i = 0; i < 6; i++) { 0126 s >> tmp16; 0127 board.mBoard[i] = tmp16; 0128 } 0129 return s; 0130 } 0131 0132 // Create hashkey for a board 0133 uint qHash(const AIBoard &key) 0134 { 0135 uint h; 0136 h = (key.mCurrent & 1) << 15; 0137 0138 h += key.mBoard[0]; 0139 h += key.mBoard[1] << 1; 0140 h += key.mBoard[2]; 0141 h += (~(key.mBoard[3])) & 0x7fff; 0142 h += (~(key.mBoard[4] << 1)) & 0x7fff; 0143 h += (~(key.mBoard[5])) & 0x7fff; 0144 0145 return h; 0146 } 0147 0148 // Create a value structure. Fill it with an unused value as 0149 // marker for 'unused'. 0150 AIValue::AIValue() 0151 { 0152 for (int i = 0; i < NO_OF_LEVELS; i++) { 0153 mValue[i] = 0x40000000; 0154 } 0155 } 0156 0157 // Store a value for a given level. 0158 void AIValue::setValue(int level, long value) 0159 { 0160 if (level < 0 || level >= NO_OF_LEVELS) { 0161 fprintf(stderr, "AIValue::setValue: Level %d not supported\n", level); 0162 fflush(stderr); 0163 return; 0164 } 0165 mValue[level] = value; 0166 } 0167 0168 // Retrieve a value for a given level. 0169 long AIValue::value(int level) const 0170 { 0171 if (level < 0 || level >= NO_OF_LEVELS) { 0172 fprintf(stderr, "AIValue::value: Level %d not supported\n", level); 0173 fflush(stderr); 0174 return 0; 0175 } 0176 return mValue[level]; 0177 } 0178 0179 // Check whether a given level has a stored value. 0180 bool AIValue::isSet(int level) const 0181 { 0182 if (level < 0 || level >= NO_OF_LEVELS) { 0183 fprintf(stderr, "AIValue::isSet: Level %d not supported\n", level); 0184 fflush(stderr); 0185 return 0; 0186 } 0187 if (mValue[level] == 0x40000000) 0188 return false; 0189 return true; 0190 } 0191 0192 // Stream a value 0193 QDataStream &operator<<(QDataStream &s, const AIValue &value) 0194 { 0195 for (int i = 0; i < AIValue::NO_OF_LEVELS; i++) 0196 s << (qint32)value.mValue[i]; 0197 return s; 0198 } 0199 0200 // Stream a value 0201 QDataStream &operator>>(QDataStream &s, AIValue &value) 0202 { 0203 qint32 tmp32; 0204 for (int i = 0; i < AIValue::NO_OF_LEVELS; i++) { 0205 s >> tmp32; 0206 value.mValue[i] = tmp32; 0207 } 0208 return s; 0209 }