summaryrefslogtreecommitdiff
path: root/bots/bot.py
blob: cc09936d1994ef9b847093acf5e76910300c46eb (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
133
134
135
136
137
138
139
140
141
142
143
144
""" bots/bot.py - bottien kantaisä """
from tui import Action
from board import Tile

class Bot():
    """ Bot - perusluokka perittäväksi """
    def __init__(self, **opts):
        self.uncertain = opts['uncertain'] if 'uncertain' in opts else False
        self.safe_tiles = set()
        self.mine_tiles = set()
        self.matrix = []
        self.w = 0
        self.h = 0

    def search(self):
        """ search - etsii pommeja tai vapaita ko joukkoihin """
        return False

    def lucky_guess(self):
        """ lucky_guess - lisää yhden arvatun vapaan vapaiden joukkoon """
        return Action.NOOP, 0, 0

    def get_hint_from_list(self):
        """ palauttaa vihjeen suoraan listalta """
        if self.safe_tiles:
            x, y = self.safe_tiles.pop()
            return Action.SAFE, x, y
        if self.mine_tiles:
            x, y = self.mine_tiles.pop()
            return Action.MINE, x, y
        return Action.NOOP, 0, 0

    def saved_hints(self):
        """ onko muuveja varastossa """
        return self.safe_tiles or self.mine_tiles

    def hint(self, matrix, cursor_x, cursor_y):
        """ antaa vinkin. tässä tapauksessa ei mitään """
        self.matrix = matrix
        self.w, self.h = self.get_dimensions()

        if self.saved_hints():
            return self.get_hint_from_list()
        if self.search():
            return self.get_hint_from_list()
        if self.uncertain and self.lucky_guess():
            return self.get_hint_from_list()
        return Action.NOOP, cursor_x, cursor_y

    def get_dimensions(self):
        """ palauttaa matriisin dimensiot """
        return len(self.matrix), len(self.matrix[0])

    def get_neighbours(self, tile):
        """ palauttaa viereiset koordinaatit joukkona """
        x, y = tile
        offsets = (
            (-1, -1), ( 0, -1), ( 1, -1),
            (-1,  0),           ( 1,  0),
            (-1,  1), ( 0,  1), ( 1,  1),
        )
        tiles=set()
        for ox, oy in offsets:
            if ox+x in range(self.w):
                if oy+y in range(self.h):
                    tiles.add((ox+x, oy+y))
        return tiles

    def get_value(self, tile):
        """ palauttaa laatan arvon """
        return self.matrix[tile[0]][tile[1]]

    def remove_number_tiles(self, tiles):
        """ poistaa vapaat ja vapaaksi merkityt alueet ja numerolaatat """
        for tile in list(tiles):
            if self.matrix[tile[0]][tile[1]] < Tile.FLAG_MINE:
                tiles.remove(tile)

    def remove_mine_tiles(self, tiles):
        """ poistaa pommit ja pommiksi merkityt """
        count=0
        for tile in list(tiles):
            if self.matrix[tile[0]][tile[1]] in (Tile.MINE, Tile.FLAG_MINE):
                tiles.remove(tile)
                count+=1
        return count

    def known_tile(self, tile):
        """ tutkii onko laatta tiedetty """
        return self.matrix[tile[0]][tile[1]] < Tile.UNOPENED

    def number_tile(self, tile):
        """ tutkii onko numerolaatta """
        return 0 < self.matrix[tile[0]][tile[1]] < Tile.MINE

    def count_unknowns(self, tiles):
        """ laskee tunnistamattomat laatat """
        count=0
        for tile in list(tiles):
            if not self.known_tile(tile):
                count+=1
        return count

    def remove_unknowns(self, tiles):
        """ poistaa tunnistamattomat laatat """
        count=0
        for tile in list(tiles):
            if not self.known_tile(tile):
                tiles.remove(tile)
                count+=1
            return count

    def get_interesting_tiles(self):
        """ palauttaa laatat joiden naapureissa on vaihtelua """
        tiles = set()
        for x in range(self.w):
            for y in range(self.h):
                if self.number_tile((x,y)):
                    n = self.get_neighbours((x,y))
                    l = len(n)
                    r = self.count_unknowns(n)
                    if r in range(1,l-1):
                        tiles.add((x,y))
        return tiles

    def get_border_tiles(self):
        """ palauttaa palauttaa numerolaatat joiden vieressä avaamaton """
        tiles = set()
        for x in range(self.w):
            for y in range(self.h):
                if self.number_tile((x,y)):
                    n = self.get_neighbours((x,y))
                    if self.count_unknowns(n):
                        tiles.add((x,y))
        return tiles

    def get_unknown_tiles(self):
        """ palauttaa kaikki tuntemattomat laatat """
        tiles = set()
        for x in range(self.w):
            for y in range(self.h):
                if not self.known_tile((x,y)):
                    tiles.add((x,y))
        return tiles