ksquares
aicontroller.cpp
Go to the documentation of this file.
19 aiController::aiController(int newPlayerId, const QList<bool> &newLines, const QList<int> &newSquareOwners, int newWidth, int newHeight) : squareOwners(newSquareOwners), playerId(newPlayerId), width(newWidth), height(newHeight)
163 if(countBorderLines(adjacentSquares.at(j), lines) == 2) //don't want to make 3 lines around a square
181 QMap<int,int> linePointDamage; //this will be a list of how damaging a certain move will be. Key = damage of move, Value = index of line
182 QScopedArrayPointer<bool> linesCopy(new bool[linesSize]); //make temporary local copies of lists
185 QMap<int, QSet<int> > chains; // this is a raw list of chains (which are sets of lines). key = random element of chain
187 QList<QList<int> > ownChains; // chains that ai will get in this run. those chains are taken in myLines.
188 QList<int> ownMoves; // contains lines of chain that the ai will take first (this will contain the returned move)
195 memcpy(myLines.data(), lines, linesSize); // lines --> myLines (complete own chains) --> linesCopy (analyze damage/chains for next runs)
197 // since chooseLeastDamaging will be called early during the game if playing against hard ai, we need to finish open chains in linesCopy before computing the number of residual chains
201 for(int curSquare = 0; curSquare < squareOwners.size(); curSquare++) // walk through squares and search for start of chain
254 // complete the shortest chain first if there is more than one chain. this is needed to stop alternating between two chains because that works against the hard ai move which takes the next chain by sacrificing 2/4 squares. when alternating between two chains it's possible that there are 3 remaining open lines in both chains combined which triggers the evil move too late because the chains were completed in the wrong order
287 //now it would be the next player's turn so we're going to count how many squares they would be able to get.
288 int count = 0; //this is how many points the next player will ge if you draw a line at choiceList.at(i)
293 for(int currentSquare=0; currentSquare<squaresCopy.size(); currentSquare++) //cycle through the grid (by squares):
295 if(countBorderLines(sidesOfSquare, currentSquare, &(*linesCopy)) == 3) //if we've found a square with three sides drawn:
300 for(int sideOfSquare=0; sideOfSquare<=3; sideOfSquare++) //make the square complete in linesCopy
317 break; //since we found a square with 3 sides completed (now = 4), we break the 'for(currentSquare)' loop
333 QList<int> bestMoves = linePointDamage.values(linePointDamage.begin().key()); //this is a list of the indices of the lines that are the least damaging. linePointDamage.begin() returns the 1st pair in the QMap, sorted in ascending order by Key (damage of move)
385 (ownLinesCnt == 3 && ownSquaresCnt == 4) // this is for loop chains which require a sacrifice of 4 squares
394 int magicLine = -1; // line in own moves that is used to get the next chain (draw there to give 2/4 squares to opponent)
395 // formal definition of magicLine: line that when completed will leave at least one other line in own moves that completes two squares at once
396 // the opposite of magic line will be used in the hard hearted handout to make sure that the opponent won't be able to do the evil move
413 if (leftSquares == 2) // we found a line that will yield another line in own moves that completes two squares
428 bestMoves.append(ownMoves.at(ownMove)); // choose the second line found! in case of 2 squares for ai this will choose the line at the end of the chain. in case of 4 squares this will be the line in the middle, leaving two lines that complete two squares each. FIX: 1 doesn't work in some cases because the algorithm doesn't detect chains by spatial connectedness. ie if there are two ends of a chain the search algorithm can jump between those two ends, messing up the order in ownMoves list. solution is magicLine
486 QList<int> bestMoves = linePointDamage.values(linePointDamage.begin().key()); //this is a list of the indices of the lines that are the least damaging. linePointDamage.begin() returns the 1st pair in the QMap, sorted in ascending order by Key (damage of move)
490 int aiController::countBorderLines(int *sidesOfSquare, int squareIndex, const bool *linesList) const
531 squareList.append(lineIndex - ( (lineIndex/((width*2)+1))*width + (lineIndex/((width*2)+1)) + width ));
void clear()
void linesFromSquare(int *sidesOfSquare, int squareIndex) const
Definition: aicontroller.cpp:543
QList< T > values() const
int size() const
const T & at(int i) const
void removeAt(int i)
Definition: aicontroller.h:15
const_iterator insert(const T &value)
int size() const
Definition: aicontroller.h:15
KSquares::Direction lineDirection(int lineIndex) const
Definition: aicontroller.cpp:555
int count(const T &value) const
void append(const T &value)
iterator insertMulti(const Key &key, const T &value)
QList< T > values() const
Item next()
QList< int > squaresFromLine(int lineIndex) const
Definition: aicontroller.cpp:515
bool isEmpty() const
const Key & key() const
const T & value() const
iterator begin()
T * data() const
bool contains(const T &value) const
int countBorderLines(int squareIndex, const bool *linesList) const
Definition: aicontroller.cpp:509
QList< int > autoFill(int safeMovesLeft)
Finds lines that can be filled without causing squares to be surrounded by 3 lines as a result...
Definition: aicontroller.cpp:33
iterator insert(const Key &key, const T &value)
aiController(int newPlayerId, const QList< bool > &newLines, const QList< int > &newSquareOwners, int newWidth, int newHeight)
Create a new AI controller.
Definition: aicontroller.cpp:19
int chooseLine() const
Choses where to draw the line: Creates a list of all the squares which are surrounded by 3 lines and ...
Definition: aicontroller.cpp:59
QList< int > chooseLeastDamaging(const QList< int > &choiceList) const
Definition: aicontroller.cpp:178
bool hasNext() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:18:39 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:18:39 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.