Advertisement
Guest User

Untitled

a guest
Jun 18th, 2024
231
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.15 KB | None | 0 0
  1. # ----06-18-2024 22:22:59----
  2.  
  3. # map to (turns to win + 1), or False
  4. winnable_cache = {}
  5.  
  6. def bestMovePlayer2(N1, N2, K1, K2, p1coins):
  7.     winByLoseRound = (p1coins > 0) and winnable(N1 - p1coins, N2, K1-1, K2)
  8.     winByWinRound = (N2-p1coins-1 >= 0) and winnable(N1-p1coins, N2-p1coins-1, K1, K2-1)
  9.     winByDrawRound = (p1coins > 0) and winnable(N1-p1coins, N2-p1coins, K1, K2)
  10.     if not winByLoseRound and not winByWinRound and not winByDrawRound:
  11.         return False
  12.     bestTurns = 1e60
  13.     if winByLoseRound:
  14.         bestTurns = winByLoseRound + 1
  15.         p2coins = 0
  16.     if winByWinRound and winByWinRound < bestTurns:
  17.         bestTurns = winByWinRound + 1
  18.         p2coins = p1coins + 1
  19.     if winByDrawRound and winByDrawRound < bestTurns:
  20.         bestTurns = winByDrawRound + 1
  21.         p2coins = p1coins
  22.     return bestTurns, p2coins
  23.  
  24. def bestMovePlayer1(N1, N2, K1, K2):
  25.     bestTurns = 0 # lose in maximum amount of turns
  26.     bestCoins = 0
  27.     for p1coins in range(N1+1):
  28.         result = bestMovePlayer2(N1, N2, K1, K2, p1coins)
  29.         if result == False:
  30.             return False # we win. unplanned for.
  31.         if result[0] > bestTurns:
  32.             bestTurns = result[0]
  33.             bestCoins = p1coins
  34.     return bestTurns, bestCoins
  35.  
  36. def winnable(N1, N2, K1, K2):
  37.     if (N1, N2, K1, K2) in winnable_cache:
  38.         return winnable_cache[(N1, N2, K1, K2)]
  39.     if K1 == 0:
  40.         winnable_cache[(N1, N2, K1, K2)] = False
  41.         return False
  42.     if K2 == 0:
  43.         winnable_cache[(N1, N2, K1, K2)] = 1
  44.         return 1
  45.     result = bestMovePlayer1(N1, N2, K1, K2)
  46.     if result == False:
  47.         winnable_cache[(N1, N2, K1, K2)] = False
  48.         return False
  49.     turns, coins = result
  50.     winnable_cache[(N1, N2, K1, K2)] = turns
  51.     return turns
  52.  
  53. def solveProblem(N, K):
  54.     for n in range(1, N+1):
  55.         for k in range(1, K+1):
  56.             winnable(n, n, k, k)
  57.     return winnable(N, N, K, K)
  58.  
  59. def fillTable(N, K):
  60.     print("N/K", end="\t")
  61.     for k in range(1, K+1):
  62.         print(k, end="\t")
  63.     print()
  64.     for n in range(1, N+1):
  65.         print(n, end="\t")
  66.         for k in range(1, K+1):
  67.             w = winnable(n, n, k, k)
  68.             if w == False:
  69.                 print("-1", end="\t")
  70.             else:
  71.                 print(w-1, end="\t")
  72.         print()
  73.  
  74. def playGame(N, K):
  75.     solveProblem(N, K)
  76.     N1, N2, K1, K2 = N, N, K, K
  77.     while True:
  78.         move1 = bestMovePlayer1(N1, N2, K1, K2)
  79.         if move1 == False:
  80.             print("Player 1 wins or draws")
  81.             break
  82.         turns, p1coins = move1
  83.         move2 = bestMovePlayer2(N1, N2, K1, K2, p1coins)
  84.         if move2 == False:
  85.             print("Hmm. This shouldn't happen.")
  86.             break
  87.         turns, p2coins = move2
  88.         print("Player 1 plays", p1coins, "and Player 2 plays", p2coins)
  89.         N1 -= p1coins
  90.         N2 -= p2coins
  91.         if p1coins > p2coins:
  92.             K1 -= 1
  93.         elif p2coins > p1coins:
  94.             K2 -= 1
  95.         print(N1, N2, K1, K2)
  96.         if K1 == 0:
  97.             print("Player 1 wins")
  98.             break
  99.         if K2 == 0:
  100.             print("Player 2 wins")
  101.             break
  102.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement