summaryrefslogtreecommitdiffstats
path: root/kenolaba/Move.h
blob: 1226d969c7fff932c000d4f29b7e390c26fce7a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* Classes Move, MoveList
 * - represents a move in the game of Abalone
 *
 * Josef Weidendorfer, 28.8.97
*/

#ifndef _MOVE_H_
#define _MOVE_H_

#include <qstring.h>

class Move
{
 public:

	/* Type of move: Moves are searched in this order */
	enum MoveType { out2 = 0, out1with3, out1with2, push2,
		  push1with3, push1with2, move3, left3, right3,
		  left2, right2, move2, move1, none };
        enum { typeCount = none };

        Move() { type = none; }
	Move(short f, char d, MoveType t)
	  { field = f; direction = d, type = t; }		
	

	bool isOutMove() const
	  { return type <= out1with2; }
	bool isPushMove() const
	  { return type <= push1with2; }
	static int maxOutType()
	  { return out1with2; }
	static int maxPushType()
	  { return push1with2; }	       
	static int maxMoveType()
	  { return move1; }	       

	QString name() const;

	void print() const;

	/* Directions */
	enum { Right=1, RightDown, LeftDown, Left, LeftUp, RightUp };
	
	short field;
	unsigned char direction;
	MoveType type;
};

/**
 * Class MoveTypeCounter
 *
 * Used in Board evaluation to count types of board allowed
 * in a position
 */
class MoveTypeCounter
{
 public:
  MoveTypeCounter();
  ~MoveTypeCounter() {}

  void init();
  void incr(int t) { count[t]++; }
  int  get(int t) { return count[t]; }
  int  sum();

 private:
  int count[Move::typeCount];
};

/**
 * Class InARowCounter
 *
 * Used in Board evaluation to count connectiveness
 * of some degrees in a position
 */
class InARowCounter
{
 public:
  enum InARowType { inARow2 = 0, inARow3, inARow4, inARow5, inARowCount };

  InARowCounter();
  ~InARowCounter() {}

  void init();
  void incr(int c) { count[c]++; }
  int  get(int c) { return count[c]; }

 private:
  int count[inARowCount];
};


/* MoveList stores a fixed number of moves (for efficince) 
 * <getNext> returns reference of next move ordered according to type
 * <insert> does nothing if there isn't enough free space
 * 
 * Recommend usage (* means 0 or more times):
 *   [ clear() ; insert() * ; isElement() * ; getNext() * ] *
 */
class MoveList
{
 public:
	MoveList();
	
	enum { MaxMoves = 150 };

	/* for isElement: search for moves starting with 1/2/3 fields */
	enum { all , start1, start2, start3 };
		
	void clear();
	void insert(Move);
	bool isElement(int f);
	bool isElement(Move&, int startType, bool del=false);
	void insert(short f, char d, Move::MoveType t)
	  { insert( Move(f,d,t) ); }
	int getLength()
	  { return nextUnused; }		  
		  
	bool getNext(Move&,int maxType);  /* returns false if no more moves */

 private:
	Move move[MaxMoves];
	int  next[MaxMoves];
	int  first[Move::typeCount];
	int  last[Move::typeCount];
	int  actual[Move::typeCount];
	int  nextUnused, actualType;
};

#endif /* _MOVE_H_ */