File indexing completed on 2024-10-13 03:44:24

0001 /*
0002     SPDX-FileCopyrightText: 2007-2008 Fela Winkelmolen <fela.kde@gmail.com>
0003     SPDX-FileCopyrightText: 2010 Brian Croom <brian.s.croom@gmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef ABSTRACT_GRID
0009 #define ABSTRACT_GRID
0010 
0011 #include <QList>
0012 #include "globals.h"
0013 
0014 class AbstractCell
0015 {
0016 public:
0017     explicit AbstractCell(int index);
0018     
0019     virtual ~AbstractCell() {}
0020     
0021     Directions cables() const {return m_cables;}
0022     int index() const {return m_index;}
0023     bool isServer() const {return m_isServer;}
0024     bool isConnected() const {return m_isConnected;}
0025     bool hasBeenMoved() const {return m_hasBeenMoved;}
0026     bool isTerminal() const;
0027     
0028     // should not be used to rotate the cell
0029     void setCables(Directions newCables);    
0030     void setServer(bool isServer);    
0031     virtual void setConnected(bool isConnected);
0032     
0033     // sets the cell as if newly created
0034     virtual void makeEmpty();
0035     
0036     void emptyMove(); // sets hasBeenMoved to true
0037     void rotateClockwise();
0038     void rotateCounterclockwise();
0039     void invert(); // rotates the cables by 180 degrees
0040     
0041     // reset to the original position
0042     void reset();
0043     
0044     // used for debugging only
0045     char *toString();
0046     
0047 private:
0048     int m_index;
0049     Directions originalCables;
0050     Directions m_cables;
0051     bool m_isServer;
0052     bool m_isConnected;
0053     bool m_hasBeenMoved;
0054 };
0055 
0056 class Move
0057 {
0058 public:
0059     enum MoveDirection {None, Left, Right, Inverted};
0060     Move() {}
0061     
0062     Move(int index, MoveDirection move) {
0063         m_index = index;
0064         m_move = move;
0065     }
0066     
0067     int index() const {return m_index;}
0068     MoveDirection move() const {return m_move;}
0069 
0070 private:
0071     int m_index;
0072     MoveDirection m_move;
0073 };
0074 
0075 typedef QList<Move> MoveList;
0076 
0077 
0078 class AbstractGrid
0079 {
0080 public:
0081     // creates a grid made of AbstractCells, which will be a valid game
0082     // this is the main purpose of the class
0083     AbstractGrid();
0084     virtual ~AbstractGrid();
0085 
0086     int width() const {return m_width;}
0087     int height() const {return m_height;}
0088     int cellCount() const {return m_cells.size();} // TODO: use in the cpp file
0089     int minimumMoves() const {return m_minimumMoves;}
0090 
0091     // ownership remains to the AbstractGrid
0092     AbstractCell *cellAt(int index) const {return m_cells[index];}
0093     void initializeGrid(uint width, uint height, Wrapping w=NotWrapped);
0094     // updates the connections of the cells
0095     // returns the indexes of the changed cells
0096     QList<int> updateConnections();
0097     // returns true if all terminals are connected to the server
0098     bool allTerminalsConnected();
0099     
0100 private:
0101     // used for debugging only
0102     void print(); // outputs the grid
0103 
0104     // used when an index of a cell is required
0105     static const int NO_CELL = -1;
0106 
0107     QList<AbstractCell *> m_cells;
0108     uint m_width;
0109     uint m_height;
0110     bool m_isWrapped;
0111     
0112     int server_index;
0113     int m_minimumMoves;
0114     
0115     //======== auxiliary functions ========//
0116     void createGrid(); // only used for modularization
0117     
0118     // adds a random direction (cable) and moves on (if possible)
0119     // used when creating the grid
0120     void addRandomCable(QList<uint>& list);
0121     // find the index to the left/right/up/down w.r.t the index given
0122     int uCell(uint cell) const;
0123     int dCell(uint cell) const;
0124     int lCell(uint cell) const;
0125     int rCell(uint cell) const;
0126     
0127     // return the opposite direction of the one given
0128     // !!! a single direction is expected as parameter (not bitwise ORed!!) !!!
0129     Directions invertDirection(Directions givenDirection);
0130     
0131     // return the number of solutions given a few moves already done
0132     int solutionCount();
0133     
0134     // returns true if you can connect all terminal without usign all cables
0135     // (doesn't really work as I wanted, doesn't detect most cases)
0136     bool hasUnneededCables();
0137     
0138     // return false if some of the moves done are clearly wrong
0139     bool movesDoneArePossible();
0140     // the minimum number of moves required to solve the game
0141 
0142     virtual AbstractCell *newCell(int index) {return new AbstractCell(index);}
0143 
0144     bool isPossibleSolution();
0145 };
0146 
0147 #endif // ABSTRACT_GRID