diff options
Diffstat (limited to 'bots')
-rw-r--r-- | bots/__init__.py | 4 | ||||
-rw-r--r-- | bots/bot.py | 142 | ||||
-rw-r--r-- | bots/dssp.py | 74 | ||||
-rw-r--r-- | bots/simple.py | 29 |
4 files changed, 0 insertions, 249 deletions
diff --git a/bots/__init__.py b/bots/__init__.py deleted file mode 100644 index f346d07..0000000 --- a/bots/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -""" bots - tämä alimoduli tarjoaa tekoälyn """ - -from .simple import SimpleBot -from .dssp import DSSPBot diff --git a/bots/bot.py b/bots/bot.py deleted file mode 100644 index 2f3baae..0000000 --- a/bots/bot.py +++ /dev/null @@ -1,142 +0,0 @@ -""" 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): - """ poistetaan auenneet laatat ja palautetaan onko muuveja """ - for tile in list(self.safe_tiles): - if self.known_tile(tile): - self.safe_tiles.remove(tile) - for tile in list(self.mine_tiles): - if self.known_tile(tile): - self.mine_tiles.remove(tile) - 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 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 diff --git a/bots/dssp.py b/bots/dssp.py deleted file mode 100644 index 0cace12..0000000 --- a/bots/dssp.py +++ /dev/null @@ -1,74 +0,0 @@ -""" bots/dssp.py - päättelee kahden vierekkäisen laatan perusteella """ -from random import sample -from .simple import SimpleBot - -class DSSPBot(SimpleBot): - """ DSSPBot - perustyhmä botti """ - - def search(self): - """ search - etsii kahden vierekkäisen laatan perusteella""" - if super().search(): - return True - tiles = list(self.get_interesting_tiles()) - pairs = [] - # pylint: disable = consider-using-enumerate - for i in range(len(tiles)): - for j in range(i+1,len(tiles)): - if abs(tiles[i][0]-tiles[j][0])==1 or abs(tiles[i][1]-tiles[j][1])==1: - pairs.append((tiles[i],tiles[j])) - pairs.append((tiles[j],tiles[i])) - - for tile1, tile2 in pairs: - c1 = self.get_value(tile1) - c2 = self.get_value(tile2) - n1 = self.get_neighbours(tile1) - n2 = self.get_neighbours(tile2) - self.remove_number_tiles(n1) - self.remove_number_tiles(n2) - c1 -= self.remove_mine_tiles(n1) - c2 -= self.remove_mine_tiles(n2) - - # otetaan vain alue1:n laatat pois vähennetään se pommeista - # näin tiedetään montako pommia on jäätävä yhteiselle alueelle - nc = n1 & n2 - n1 = n1 - nc - n2 = n2 - nc - cc = c1 - len(n1) - - # jos yhteiselle alueelle ei jääkkään pommeja - if cc < 1: - continue - - # vähennetään yhteinen alue ja sen pommit alueesta 2 - # jos jäljelle ei jää miinoja merkataan alueet seiffeiks - c2 -= cc - - if c2 == 0: - for safe in n2: - self.safe_tiles.add(safe) - - return self.saved_hints() - - def lucky_guess(self): - heatmap = dict.fromkeys(self.get_unknown_tiles(), float(0)) - tiles = self.get_border_tiles() - for tile in tiles: - n = self.get_neighbours(tile) - c = self.get_value(tile) - self.remove_mine_tiles(n) - self.remove_number_tiles(n) - for ntile in n: - heatmap[ntile] += c/len(n) - - for tile in heatmap: - if tile[0] in range(1,self.w-1): - heatmap[tile]+=0.005 - if tile[1] in range(1,self.h-1): - heatmap[tile]+=0.005 - - best = min((x for _, x in heatmap.items())) - best_tiles = [x for x,y in heatmap.items() if y == best] - - if best_tiles: - self.safe_tiles.add(sample(best_tiles,1)[0]) - return True - return False diff --git a/bots/simple.py b/bots/simple.py deleted file mode 100644 index 54e2d05..0000000 --- a/bots/simple.py +++ /dev/null @@ -1,29 +0,0 @@ -""" bots/simple.py - yksinkertainen botti joka etsii vain yhdeltä laatalta """ -from random import sample -from .bot import Bot - -class SimpleBot(Bot): - """ SimpleBot - perustyhmä botti """ - - def search(self): - """ simple_search - jos viereisten avaamattomien määrä tästmää """ - tiles = self.get_interesting_tiles() - for tile in tiles: - c = self.get_value(tile) - n = self.get_neighbours(tile) - self.remove_number_tiles(n) - c -= self.remove_mine_tiles(n) - if c == 0: - for safe in n: - self.safe_tiles.add(safe) - if c == len(n): - for mine in n: - self.mine_tiles.add(mine) - return self.saved_hints() - - def lucky_guess(self): - tiles = self.get_unknown_tiles() - if tiles: - self.safe_tiles.add(sample(sorted(tiles),1)[0]) - return True - return False |