Advertisement
Guest User

Untitled

a guest
Dec 24th, 2019
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.32 KB | None | 0 0
  1. import asyncio
  2. import time
  3. import random
  4. import copy
  5. import json
  6. import sys
  7.  
  8. class Engine:
  9.     lock = asyncio.Lock()
  10.     def __init__(self, other=None):
  11.         self.lock = asyncio.Lock()
  12.         if other == None:
  13.             self.data = {
  14.                 "p": [64] * 10,
  15.                 "n": [64] * 10,
  16.                 "b": [64] * 10,
  17.                 "r": [64] * 10,
  18.                 "q": [64] * 10,
  19.                 "k": [64] * 12 }
  20.         elif type(other) == Engine:
  21.             self.data = copy.deepcopy(other.data)
  22.         else:
  23.             self.data = copy.deepcopy(other)
  24.  
  25.     def __str__(self):
  26.         trimap = [
  27.             0, 1, 2, 3, 3, 2, 1, 0,
  28.             1, 4, 5, 6, 6, 5, 4, 1,
  29.             2, 5, 7, 8, 8, 7, 5, 2,
  30.             3, 6, 8, 9, 9, 8, 6, 3,
  31.             3, 6, 8, 9, 9, 8, 6, 3,
  32.             2, 5, 7, 8, 8, 7, 5, 2,
  33.             1, 4, 5, 6, 6, 5, 4, 1,
  34.             0, 1, 2, 3, 3, 2, 1, 0]
  35.         colmap = [0, 1, 2, 3, 3, 2, 1, 0]
  36.         psqt_pawn = [0] * 64
  37.         for row in range(6):
  38.             rv = self.data["p"][4:][row]
  39.             for col in range(8):
  40.                 cv = self.data["p"][:4][colmap[col]]
  41.                 psqt_pawn[row * 8 + 8 + col] = (rv + cv) // 2
  42.         psqt_king = [0] * 64
  43.         for row in range(8):
  44.             rv = self.data["k"][4:][row]
  45.             for col in range(8):
  46.                 cv = self.data["k"][:4][colmap[col]]
  47.                 psqt_king[row * 8 + col] = (rv + cv) // 2
  48.         return f"""#include "types.hh"
  49. namespace chess {{
  50.     extern const int psqt_avg = {sum(self.data["p"]) // len(self.data["p"])};
  51.     extern const int psqt[6][64] = {{
  52.         {{{ ",".join(str(i) for i in psqt_pawn) }}},
  53.         {{{ ",".join(str(self.data["n"][i]) for i in trimap) }}},
  54.         {{{ ",".join(str(self.data["b"][i]) for i in trimap) }}},
  55.         {{{ ",".join(str(self.data["r"][i]) for i in trimap) }}},
  56.         {{{ ",".join(str(self.data["q"][i]) for i in trimap) }}},
  57.         {{{ ",".join(str(i) for i in psqt_king) }}},
  58.     }};
  59. }}
  60. """
  61.  
  62.     def mutate(self):
  63.         for k, p in self.data.items():
  64.             for i, v in enumerate(p):
  65.                 if random.random() < 5 / 62:
  66.                     p[i] = random.gauss(v, v / 16)
  67.                     p[i] = max(32, min(512, int(round(p[i]))))
  68.  
  69.     async def move(self, pos):
  70.         async with self.lock:
  71.             self.proc.stdin.write(f"position startpos moves { ' '.join(pos) }\n".encode())
  72.             self.proc.stdin.write(f"go movetime 25\n".encode())
  73.             await self.proc.stdin.drain()
  74.             score = 0
  75.             while True:
  76.                 line = await self.proc.stdout.readline()
  77.                 data = line.decode().strip().split(" ")
  78.                 if data[0] == "bestmove":
  79.                     if data[1] == "0000":
  80.                         return score
  81.                     pos.append(data[1])
  82.                     return None
  83.                 elif data[0] == "info":
  84.                     score = int(data[3])
  85.                 else:
  86.                     print(pos)
  87.                     sys.exit(1)
  88.  
  89.     async def open(self):
  90.         async with Engine.lock:
  91.             with open("src/eval.cc", "w") as f:
  92.                 f.write(str(self))
  93.             make = await asyncio.create_subprocess_exec("./make.sh")
  94.             await make.wait()
  95.             self.proc = await asyncio.create_subprocess_shell("./chess",
  96.                 stdout=asyncio.subprocess.PIPE,
  97.                 stdin=asyncio.subprocess.PIPE)
  98.  
  99.     async def close(self, *args):
  100.         self.proc.stdin.write_eof()
  101.         await self.proc.wait()
  102.         del self.proc
  103.  
  104.     async def play(e1, e2, pos=None):
  105.         if pos == None:
  106.             pos = []
  107.         score = await e1.move(pos)
  108.         if score != None:
  109.             return score
  110.         return -await Engine.play(e2, e1, pos)
  111.  
  112. async def main():
  113.     try:
  114.         try:
  115.             with open("temp.json", "r") as f:
  116.                 data = json.load(f)
  117.         except:
  118.             data = None
  119.         engines = [Engine(data)]
  120.         await engines[0].open()
  121.         while True:
  122.             while len(engines) < 6:
  123.                 engines.append(Engine(engines[0]))
  124.                 engines[-1].mutate()
  125.                 await engines[-1].open()
  126.             results = []
  127.             for e1 in engines:
  128.                 games = []
  129.                 for e2 in engines:
  130.                     if e1 == e2:
  131.                         async def null():
  132.                             return 0
  133.                         games.append(null())
  134.                     else:
  135.                         games.append(Engine.play(e1, e2))
  136.                 results.append(asyncio.gather(*games))
  137.             results = await asyncio.gather(*results)
  138.             scores = [0] * len(engines)
  139.             for i, v in enumerate(results):
  140.                 for j, w in enumerate(v):
  141.                     if w == 0:
  142.                         scores[i] += 1
  143.                         scores[j] += 1
  144.                     elif w < 0:
  145.                         scores[j] += 2
  146.                     elif w > 0:
  147.                         scores[i] += 2
  148.             best_index = 0
  149.             for i, v in enumerate(scores):
  150.                 if v > scores[best_index]:
  151.                     best_index = i
  152.             print(f"win {best_index}: {scores[best_index]}")
  153.             with open("temp.json", "w") as f:
  154.                 json.dump(engines[best_index].data, f)
  155.             engines.insert(0, engines.pop(best_index))
  156.             while len(engines) > 1:
  157.                 await engines.pop().close()
  158.     finally:
  159.         for engine in engines:
  160.             await engine.close()
  161.  
  162. if __name__ == "__main__":
  163.     asyncio.run(main())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement