File indexing completed on 2022-09-27 13:19:28

0001 /* 0002 SPDX-FileCopyrightText: 2006 Matthew Williams <matt@milliams.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef AICONTROLLER_H 0008 #define AICONTROLLER_H 0009 0010 #include <QList> 0011 0012 namespace KSquares 0013 { 0014 enum Direction {HORIZONTAL, VERTICAL}; 0015 } 0016 0017 /** 0018 * @short AI Controller for KSquares 0019 * 0020 * When playing a game of squares there are a number of stages the game goes through: 0021 * @li The random line placement stage. Where players are just placing lines while trying to not complete the third side of any squares 0022 * @li Next players will try to only draw the third side of a square if it will only give the opponent the minimum amount of points 0023 * @li The more advanced player will, at the end of a large run of squares leave a small area at the end, forcing the opponent to take only that small section, leaving another large area open to him. 0024 * @li The even more advanced player will fight for control over the game. This means that he will count the chains forming in the last phase of the "random line" game phase and thus make sure that he will be the one who gets the first long chain. This works like a Nim game somehow. 0025 * Currently, the first three points are implemented. 0026 * 0027 * @author Matt Williams <matt@milliams.com> 0028 * @author Tom Vincent Peters <kde@vincent-peters.de> 0029 */ 0030 0031 class aiController 0032 { 0033 public: 0034 /** 0035 * Create a new AI controller 0036 * 0037 * @param newPlayerId ID of the player 0038 * @param newLines list of the lines which are drawn 0039 * @param newSquareOwners list of squares and their owners 0040 * @param newWidth height of the current gameboard 0041 * @param newHeight width of the current gameboard 0042 */ 0043 aiController(int newPlayerId, const QList<bool> &newLines, const QList<int> &newSquareOwners, int newWidth, int newHeight); 0044 0045 ~aiController(); 0046 0047 /** 0048 * Choses where to draw the line: 0049 * Creates a list of all the squares which are surrounded by 3 lines and if the list isn't empty, randomly picks one of them. 0050 * Otherwise, creates a list of all the squares which are surrounded by 1 or 2 lines and if the list isn't empty, randomly chooses one of them. 0051 * Otherwise, randomly chooses a square which is surrounded by three lines. 0052 * 0053 * @return The index of the line from "QVector<bool> lines" 0054 */ 0055 int chooseLine() const; 0056 /** 0057 * Finds lines that can be filled without causing squares to be surrounded by 3 lines as a result. 0058 * @param safeMovesLeft number of safe moves that can be performed after those returned by the function are drawn (note: the number is valid only for a certain sequence, for other sequences they could either be more or less) 0059 * 0060 * @return the list of lines that can be safely drawn 0061 */ 0062 QList<int> autoFill(int safeMovesLeft); 0063 0064 protected: 0065 /** 0066 * @return list of moves that are safe (squares surrounded by 2 lines are avoided) 0067 */ 0068 QList<int> safeMoves() const; 0069 /** 0070 * @param choiceList list of indices (of lines) which have squares next to them with two lines drawn (relates to @ref lines ) 0071 * 0072 * @return list of indices (of lines) which would be the least damaging in the short term 0073 */ 0074 QList<int> chooseLeastDamaging(const QList<int> &choiceList) const; 0075 /** 0076 * @param squareIndex the index of the square (relates to @ref squareOwners ) 0077 * @param linesList the linesList you want to work from 0078 * 0079 * @return the number of lines currently drawn around a specific square 0080 */ 0081 int countBorderLines(int squareIndex, const bool *linesList) const; 0082 /** 0083 * @param sidesOfSquare output parameter: the indices of the four lines surrounding the square 0084 * @param squareIndex the index of the square (relates to @ref squareOwners ) 0085 * @param linesList the linesList you want to work from 0086 * 0087 * @return the number of lines currently drawn around a specific square 0088 */ 0089 int countBorderLines(int *sidesOfSquare, int squareIndex, const bool *linesList) const; 0090 /** 0091 * @param lineIndex the index of the line (relates to @ref lines ) 0092 * 0093 * @return the (one or two) squares abutting a line 0094 */ 0095 QList<int> squaresFromLine(int lineIndex) const; 0096 /** 0097 * @param sidesOfSquare output parameter: the indices of the four lines surrounding the square 0098 * @param squareIndex the index of the square (relates to @ref squareOwners ) 0099 */ 0100 void linesFromSquare(int *sidesOfSquare, int squareIndex) const; 0101 /** 0102 * @param lineIndex the index of the line (relates to @ref lines ) 0103 * 0104 * @return the direction of the line 0105 */ 0106 KSquares::Direction lineDirection(int lineIndex) const; 0107 0108 /// List of the owners of each square 0109 QList<int> squareOwners; 0110 /// List of which lines are complete 0111 int linesSize; 0112 bool *lines; 0113 /// The ID of the player this AI belongs to 0114 int playerId; 0115 /// Width of the game board 0116 int width; 0117 /// Height of the game board 0118 int height; 0119 }; 0120 0121 #endif // KSQUARES_H