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
|
""" bots/dssp.py - päättelee kahden vierekkäisen laatan perusteella """
from random import choice
from .simple import SimpleBot
class DSSPBot(SimpleBot):
""" Kahden pisteen naapureita tutkiva tekoäly. Pohjana SipleBot tekoäly."""
def search(self):
""" Etsitään voiko viereisen numerolaatan osoittamat miinat ja
epävarmat poistamalla päätellä onko jokin nykyisen laatan tuntematon
vapaa. """
if super().search():
return True
for tile1, tile2 in self.get_pairs():
unknowns1, minecount1 = self.get_unknowns_and_minecount(tile1)
unknowns2, minecount2 = self.get_unknowns_and_minecount(tile2)
# Kun 1. alueen miinoista vähennetään vain 1. alueella olevat
# tuntemattomat laatat saadaan vähimmäismäärä miinoille yhteisellä
# alueella.
common_minecount = minecount1 - len(unknowns1-unknowns2)
# Turha jatkaa jos yhteiselle alueelle ei tarvitse asettaa miinoja.
if common_minecount < 1:
continue
# Vähennetään yhteiset tuntemattomat 2. alueen tuntemattomista.
unknowns2 = unknowns2 - unknowns1
# Jos 2. alueelle ei jää tuntemattomia ei tarvitse jatkaa
if not unknowns2:
continue
# Vähennetään 2. aluuen miinoista ne jotka on pakko sijoittaa
# yhteiselle alueella
minecount2 -= common_minecount
# Jos 2. alueelle ei jää yhtään miinaa tiedetään kaikki
# tuntemattomat siellä vapaiksi
if minecount2 == 0:
self.safe_tiles |= unknowns2
return self.saved_hints()
def get_pairs(self):
""" Etsii kiinnostavien laattojen joukosta vierekkäiset """
tiles = list(self.get_interesting_tiles())
pairs = []
for i, tile1 in enumerate(tiles):
for _, tile2 in enumerate(tiles, i+1):
if self.are_neighbours(tile1,tile2):
pairs.append((tile1,tile2))
pairs.append((tile2,tile1))
return pairs
def lucky_guess(self):
""" Tehdään arvaus kylmimpien laattojen joukosta """
heatmap = dict.fromkeys(self.get_unknown_tiles(), float(0))
# Lisätään lämpöä viereisten tuntemattomien ja jäljellä olevien
# miinojen suhteen verran.
for tile in self.get_border_tiles():
unknowns, minecount = self.get_unknowns_and_minecount(tile)
for utile in unknowns:
heatmap[utile] += minecount/len(unknowns)
# Lisätään lämpöä keskimmäisiin laattoihin. Kulmat ei saa lämpöä.
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
# Etsitään kylmin arvo ja kylmimmät laatat ja arvotaan niistä yksi.
coolest_value = min((x for _, x in heatmap.items()))
coolest_tiles = [x for x,y in heatmap.items() if y == coolest_value]
self.safe_tiles.add(choice(coolest_tiles))
return True
|