summaryrefslogtreecommitdiff
path: root/bag.h
blob: fd44d6eaaebb283b15d41377e32759e695b3ce2b (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
/*
 *  Quackle -- Crossword game artificial intelligence and analysis tool
 *  Copyright (C) 2005-2019 Jason Katz-Brown, John O'Laughlin, and John Fultz.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef QUACKLE_BAG_H
#define QUACKLE_BAG_H

#include "alphabetparameters.h"
#include "rack.h"

using namespace std;

namespace Quackle
{

class Move;

class Bag
{
public:
	Bag();
	Bag(const LetterString &contents);

	void clear();

	void exch(const Move &move, Rack &rack);

	// removes and returns a random letter from bag
	Letter pluck();

	// returns true if all letters were in the bag before
	// and were removed
	bool removeLetters(const LetterString &letters);
	bool removeLetters(const LongLetterString &letters);

	// returns true if the letter was in the bag and was
	// removed
	bool removeLetter(Letter letter);

	// how many of each letter are in the bag
	void letterCounts(char *countsArray) const;

	// put letters back in the bag
	void toss(const LetterString &letters);
	void toss(const LongLetterString &letters);
	void toss(const Rack &rack);

	// Fill rack up with tiles from the bag picked in random order.
	// Alphabetizes rack.
	void refill(Rack &rack);

	// Fill rack up with tiles from the bag picked in drawingOrder,
	// starting from the back of the LetterString.
	// Returns letters from drawingOrder that weren't added to the bag.
	// Alphabetizes rack.
	LetterString refill(Rack &rack, const LetterString &drawingOrder);

	// use this to start out your bag for use
	void prepareFullBag();

	// Assuming a full bag, how many tiles would that be?
	int fullBagTileCount();

	// whether there are no tiles left in the bag
	bool empty() const;

	// returns number of tiles left in the bag
	int size() const;

	const LongLetterString &tiles() const;
	
	// returns our tiles in a random order
	LongLetterString shuffledTiles() const;

	// returns as many of our tiles in a random order as will
	// fit in a regular LetterString
	LetterString someShuffledTiles() const;

	static double probabilityOfDrawingFromFullBag(const LetterString &letters);
	static double probabilityOfDrawingFromBag(const LetterString &letters, const Bag &bag);
	double probabilityOfDrawing(const LetterString &letters);

	UVString toString() const;

private:
	// remove letter from the bag
	Letter erase(int pos);

	LongLetterString m_tiles;
};

inline void Bag::toss(const Rack &rack)
{
	toss(rack.tiles());
}

inline bool Bag::empty() const
{
    return m_tiles.empty();
}

inline int Bag::size() const
{
    return (int)m_tiles.size();
}

inline const LongLetterString &Bag::tiles() const
{
	return m_tiles;
}

}

UVOStream &operator<<(UVOStream &o, const Quackle::Bag &bag);

#endif