- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
为了方便别人帮助我我已将所有代码放在这里 https://pastebin.com/WENzM41k 它将从 2 个代理相互竞争开始。
我正在尝试实现蒙特卡洛树搜索以在 Python 中玩 9 棋盘井字游戏。游戏规则类似于常规井字游戏,但有 9 个 3x3 子板。最后一 block 的放置位置决定了放置您的 block 的子板。这有点像终极井字游戏,但如果其中一个子棋盘获胜,游戏就结束了。
我正在尝试学习 MCTS,我在这里找到了一些代码: http://mcts.ai/code/python.html
我在网站上使用了节点类和 UCT 类,并添加了我的 9 棋盘井字游戏状态类和一些其他代码。所有代码都在这里:
from math import log, sqrt
import random
import numpy as np
from copy import deepcopy
class BigGameState:
def __init__(self):
self.board = np.zeros((10, 10), dtype="int8")
self.curr = 1
self.playerJustMoved = 2 # At the root pretend the player just moved is player 2 - player 1 has the first move
def Clone(self):
""" Create a deep clone of this game state.
"""
st = BigGameState()
st.playerJustMoved = self.playerJustMoved
st.curr = self.curr
st.board = deepcopy(self.board)
return st
def DoMove(self, move):
""" Update a state by carrying out the given move.
Must update playerJustMoved.
"""
self.playerJustMoved = 3 - self.playerJustMoved
if move >= 1 and move <= 9 and move == int(move) and self.board[self.curr][move] == 0:
self.board[self.curr][move] = self.playerJustMoved
self.curr = move
def GetMoves(self):
""" Get all possible moves from this state.
"""
return [i for i in range(1, 10) if self.board[self.curr][i] == 0]
def GetResult(self, playerjm):
""" Get the game result from the viewpoint of playerjm.
"""
for bo in self.board:
for (x,y,z) in [(1,2,3),(4,5,6),(7,8,9),(1,4,7),(2,5,8),(3,6,9),(1,5,9),(3,5,7)]:
if bo[x] == [y] == bo[z]:
if bo[x] == playerjm:
return 1.0
else:
return 0.0
if self.GetMoves() == []: return 0.5 # draw
def drawboard(self):
print_board_row(self.board, 1, 2, 3, 1, 2, 3)
print_board_row(self.board, 1, 2, 3, 4, 5, 6)
print_board_row(self.board, 1, 2, 3, 7, 8, 9)
print(" ------+-------+------")
print_board_row(self.board, 4, 5, 6, 1, 2, 3)
print_board_row(self.board, 4, 5, 6, 4, 5, 6)
print_board_row(self.board, 4, 5, 6, 7, 8, 9)
print(" ------+-------+------")
print_board_row(self.board, 7, 8, 9, 1, 2, 3)
print_board_row(self.board, 7, 8, 9, 4, 5, 6)
print_board_row(self.board, 7, 8, 9, 7, 8, 9)
print()
def print_board_row(board, a, b, c, i, j, k):
# The marking script doesn't seem to like this either, so just take it out to submit
print("", board[a][i], board[a][j], board[a][k], end = " | ")
print(board[b][i], board[b][j], board[b][k], end = " | ")
print(board[c][i], board[c][j], board[c][k])
class Node:
""" A node in the game tree. Note wins is always from the viewpoint of playerJustMoved.
Crashes if state not specified.
"""
def __init__(self, move = None, parent = None, state = None):
self.move = move # the move that got us to this node - "None" for the root node
self.parentNode = parent # "None" for the root node
self.childNodes = []
self.wins = 0
self.visits = 0
self.untriedMoves = state.GetMoves() # future child nodes
self.playerJustMoved = state.playerJustMoved # the only part of the state that the Node needs later
def UCTSelectChild(self):
""" Use the UCB1 formula to select a child node. Often a constant UCTK is applied so we have
lambda c: c.wins/c.visits + UCTK * sqrt(2*log(self.visits)/c.visits to vary the amount of
exploration versus exploitation.
"""
s = sorted(self.childNodes, key = lambda c: c.wins/c.visits + 0.2 * sqrt(2*log(self.visits)/c.visits))[-1]
return s
def AddChild(self, m, s):
""" Remove m from untriedMoves and add a new child node for this move.
Return the added child node
"""
n = Node(move = m, parent = self, state = s)
self.untriedMoves.remove(m)
self.childNodes.append(n)
return n
def Update(self, result):
""" Update this node - one additional visit and result additional wins. result must be from the viewpoint of playerJustmoved.
"""
self.visits += 1
self.wins += result
def __repr__(self):
return "[M:" + str(self.move) + " W/V:" + str(self.wins) + "/" + str(self.visits) + " U:" + str(self.untriedMoves) + "]"
def TreeToString(self, indent):
s = self.IndentString(indent) + str(self)
for c in self.childNodes:
s += c.TreeToString(indent+1)
return s
def IndentString(self,indent):
s = "\n"
for i in range (1,indent+1):
s += "| "
return s
def ChildrenToString(self):
s = ""
for c in self.childNodes:
s += str(c) + "\n"
return s
def UCT(rootstate, itermax, verbose = False):
""" Conduct a UCT search for itermax iterations starting from rootstate.
Return the best move from the rootstate.
Assumes 2 alternating players (player 1 starts), with game results in the range [0.0, 1.0]."""
rootnode = Node(state = rootstate)
for i in range(itermax):
node = rootnode
state = rootstate.Clone()
# Select
while node.untriedMoves == [] and node.childNodes != []: # node is fully expanded and non-terminal
node = node.UCTSelectChild()
state.DoMove(node.move)
# Expand
if node.untriedMoves != []: # if we can expand (i.e. state/node is non-terminal)
m = random.choice(node.untriedMoves)
state.DoMove(m)
node = node.AddChild(m,state) # add child and descend tree
# Rollout - this can often be made orders of magnitude quicker using a state.GetRandomMove() function
while state.GetMoves() != []: # while state is non-terminal
state.DoMove(random.choice(state.GetMoves()))
# Backpropagate
while node != None: # backpropagate from the expanded node and work back to the root node
node.Update(state.GetResult(node.playerJustMoved)) # state is terminal. Update node with result from POV of node.playerJustMoved
node = node.parentNode
# Output some information about the tree - can be omitted
if (verbose): print(rootnode.TreeToString(0))
else: print(rootnode.ChildrenToString())
return sorted(rootnode.childNodes, key = lambda c: c.visits)[-1].move # return the move that was most visited
def UCTPlayGame():
""" Play a sample game between two UCT players where each player gets a different number
of UCT iterations (= simulations = tree nodes).
"""
state = BigGameState() # uncomment to play OXO
while (state.GetMoves() != []):
state.drawboard()
m = UCT(rootstate = state, itermax = 1000, verbose = False) # play with values for itermax and verbose = True
print("Best Move: " + str(m) + "\n")
state.DoMove(m)
if state.GetResult(state.playerJustMoved) == 1.0:
print("Player " + str(state.playerJustMoved) + " wins!")
elif state.GetResult(state.playerJustMoved) == 0.0:
print("Player " + str(3 - state.playerJustMoved) + " wins!")
else: print("Nobody wins!")
if __name__ == "__main__":
""" Play a single game to the end using UCT for both players.
"""
UCTPlayGame()
运行代码,它将在 2 个代理相互竞争时启动。但是,代理不能很好地玩游戏。糟糕的比赛是 Not Acceptable 。例如,如果 ai 在子棋盘中连续获得 2,并且又轮到他了,他就不会下获胜棋步。我应该从哪里开始改进以及如何改进?我尝试更改 Node 类和 UCT 类的代码,但没有任何效果。
更新:如果棋盘处于以下状态,则轮到我的AI(打X)玩棋盘8(第三排中间的子棋盘)。我应该编写特定代码让 AI 不玩 1 或 5(因为那样对手会赢)还是应该让 AI 来决定。我尝试编写代码告诉 AI,但那样我必须遍历所有子板。
--O|---|---
-O-|---|---
---|---|---
-----------
---|-O-|---
---|-O-|---
---|---|---
-----------
---|---|---
---|---|---
---|---|---
最佳答案
我花了一些时间阅读有关 MCTS 的内容,并花了更多时间来捕捉其余的错误:
NegamaxPlayer 与 UCT(蒙特卡洛树搜索)
itermax= won lost draw total_time
1 964 0 36 172.8
10 923 0 77 173.4
100 577 0 423 182.1
1000 48 0 952 328.9
10000 0 0 1000 1950.3
UTC 对完美玩家的表现相当令人印象深刻(minimax 进行完整的三搜索):itermax=1000 时得分和玩时间几乎相等 - 1000 场比赛中只有 48 场输掉。
我在 NegamaxPlayer 中添加了一个深度限制来玩 9 棋盘井字游戏,因为在这个游戏中可能需要一段时间才能找到最佳着法。
NegamaxPlayer(深度)与 UCT(itermax)
depth itermax won lost draw total_time
4 1 9 1 0 18.4
4 10 9 1 0 20.7
4 100 5 5 0 36.2
4 1000 2 8 0 188.8
5 10000 2 8 0 318.0
6 10000 0 10 0 996.5
现在UTC(itermax=100)和NegamaxPlayer(depth 4)玩同一个关卡,在下一个关卡8比2获胜。我很惊讶! ;-)
我在该级别 (itermax=100) 赢得了第一场比赛,但在 1000 级别输掉了第二场比赛:
Game 1, Move 40:
┏━━━━━━━┳━━━━━━━┳━━━━━━━┓
┃ X X . ┃*O O O ┃ O . . ┃
┃ . O O ┃ . . X ┃ . X O ┃
┃ O X X ┃ X . . ┃ . X . ┃
┣━━━━━━━╋━━━━━━━╋━━━━━━━┫
┃ X . . ┃ . X . ┃ O . . ┃
┃ . X . ┃ O O X ┃ O X . ┃
┃ . O . ┃ O . . ┃ X . . ┃
┣━━━━━━━╋━━━━━━━╋━━━━━━━┫
┃ X X O ┃ O . X ┃ . O X ┃
┃ X . . ┃ . . . ┃ . . . ┃
┃ . . O ┃ O . X ┃ . O . ┃
┗━━━━━━━┻━━━━━━━┻━━━━━━━┛
Player 2 wins!
won 0 lost 1 draw 0
完整代码如下:
from math import *
import random
import time
from copy import deepcopy
class BigGameState:
def __init__(self):
self.board = [[0 for i in range(10)] for j in range(10)]
self.curr = 1
# At the root pretend the player just moved is player 2,
# so player 1 will have the first move
self.playerJustMoved = 2
self.ended = False
# to put * in __str__
self.last_move = None
self.last_curr = None
def Clone(self):
return deepcopy(self)
def DoMove(self, move):
# 1 2 3
# 4 5 6
# 7 8 9
winning_pairs = [[], # 0
[[2, 3], [5, 9], [4, 7]], # for 1
[[1, 3], [5, 8]], # for 2
[[1, 2], [5, 7], [6, 9]], # for 3
[[1, 7], [5, 6]], # for 4
[[1, 9], [2, 8], [3, 7], [4, 6]], # for 5
[[3, 9], [4, 5]], # for 6
[[1, 4], [5, 3], [8, 9]], # for 7
[[7, 9], [2, 5]], # for 8
[[7, 8], [1, 5], [3, 6]], # for 9
]
if not isinstance(move, int) or 1 < move > 9 or \
self.board[self.curr][move] != 0:
raise ValueError
self.playerJustMoved = 3 - self.playerJustMoved
self.board[self.curr][move] = self.playerJustMoved
for index1, index2 in winning_pairs[move]:
if self.playerJustMoved == self.board[self.curr][index1] == \
self.board[self.curr][index2]:
self.ended = True
self.last_move = move
self.last_curr = self.curr
self.curr = move
def GetMoves(self):
if self.ended:
return []
return [i for i in range(1, 10) if self.board[self.curr][i] == 0]
def GetResult(self, playerjm):
# Get the game result from the viewpoint of playerjm.
for bo in self.board:
for x, y, z in [(1, 2, 3), (4, 5, 6), (7, 8, 9),
(1, 4, 7), (2, 5, 8), (3, 6, 9),
(1, 5, 9), (3, 5, 7)]:
if bo[x] == bo[y] == bo[z]:
if bo[x] == playerjm:
return 1.0
elif bo[x] != 0:
return 0.0
if not self.GetMoves():
return 0.5 # draw
raise ValueError
def _one_board_string(self, a, row):
return ''.join([' ' + '.XO'[self.board[a][i+row]] for i in range(3)])
def _three_board_line(self, index, row):
return '┃' + ''.join([self._one_board_string(i + index, row) + ' ┃' for i in range(3)])
def __repr__(self):
# ┏━━━━━━━┳━━━━━━━┳━━━━━━━┓
# ┃ . . . ┃ . . . ┃ . . . ┃
# ┃ . . . ┃ X . X ┃ . . O ┃
# ┃ . X . ┃ . . O ┃ . . . ┃
# ┣━━━━━━━╋━━━━━━━╋━━━━━━━┫
# ┃ . . . ┃ . . . ┃*X X X ┃
# ┃ X . O ┃ . . . ┃ O . O ┃
# ┃ . . O ┃ . . . ┃ . . . ┃
# ┣━━━━━━━╋━━━━━━━╋━━━━━━━┫
# ┃ . . . ┃ . O . ┃ . O . ┃
# ┃ . . . ┃ . . . ┃ . . X ┃
# ┃ . . . ┃ . . . ┃ . . X ┃
# ┗━━━━━━━┻━━━━━━━┻━━━━━━━┛
s = '┏━━━━━━━┳━━━━━━━┳━━━━━━━┓\n'
for i in [1, 4, 7]:
for j in [1, 4, 7]:
s += self._three_board_line(i, j) + '\n'
if i != 7:
s += '┣━━━━━━━╋━━━━━━━╋━━━━━━━┫\n'
else:
s += '┗━━━━━━━┻━━━━━━━┻━━━━━━━┛\n'
# Hack: by rows and colums of move and current board
# calculate place to put '*' so it is visible
c = self.last_curr - 1
c_c = c % 3
c_r = c // 3
m_c = (self.last_move - 1) % 3
m_r = (self.last_move - 1)// 3
p = 26 + c_r * (26 * 4) + c_c * 8 + m_r * 26 + m_c * 2 + 1
s = s[:p] + '*' + s[p+1:]
return s
class OXOState:
def __init__(self):
self.playerJustMoved = 2
self.ended = False
self.board = [0, 0, 0, 0, 0, 0, 0, 0, 0]
def Clone(self):
return deepcopy(self)
def DoMove(self, move):
# 0 1 2
# 3 4 5
# 6 7 8
winning_pairs = [[[1, 2], [4, 8], [3, 6]], # for 0
[[0, 2], [4, 7]], # for 1
[[0, 1], [4, 6], [5, 8]], # for 2
[[0, 6], [4, 5]], # for 3
[[0, 8], [1, 7], [2, 6], [3, 5]], # for 4
[[2, 8], [3, 4]], # for 5
[[0, 3], [4, 2], [7, 8]], # for 6
[[6, 8], [1, 4]], # for 7
[[6, 7], [0, 4], [2, 5]], # for 6
]
if not isinstance(move, int) or 0 < move > 8 or \
self.board[move] != 0:
raise ValueError
self.playerJustMoved = 3 - self.playerJustMoved
self.board[move] = self.playerJustMoved
for index1, index2 in winning_pairs[move]:
if self.playerJustMoved == self.board[index1] == self.board[index2]:
self.ended = True
def GetMoves(self):
return [] if self.ended else [i for i in range(9) if self.board[i] == 0]
def GetResult(self, playerjm):
for (x, y, z) in [(0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6), (1, 4, 7),
(2, 5, 8), (0, 4, 8), (2, 4, 6)]:
if self.board[x] == self.board[y] == self.board[z]:
if self.board[x] == playerjm:
return 1.0
elif self.board[x] != 0:
return 0.0
if self.GetMoves() == []:
return 0.5 # draw
raise ValueError
def __repr__(self):
s = ""
for i in range(9):
s += '.XO'[self.board[i]]
if i % 3 == 2: s += "\n"
return s
class Node:
""" A node in the game tree. Note wins is always from the viewpoint of playerJustMoved.
Crashes if state not specified.
"""
def __init__(self, move=None, parent=None, state=None):
self.move = move # the move that got us to this node - "None" for the root node
self.parentNode = parent # "None" for the root node
self.childNodes = []
self.wins = 0
self.visits = 0
self.untriedMoves = state.GetMoves() # future child nodes
self.playerJustMoved = state.playerJustMoved # the only part of the state that the Node needs later
def UCTSelectChild(self):
""" Use the UCB1 formula to select a child node. Often a constant UCTK is applied so we have
lambda c: c.wins/c.visits + UCTK * sqrt(2*log(self.visits)/c.visits to vary the amount of
exploration versus exploitation.
"""
s = sorted(self.childNodes, key=lambda c: c.wins / c.visits + sqrt(
2 * log(self.visits) / c.visits))[-1]
return s
def AddChild(self, m, s):
""" Remove m from untriedMoves and add a new child node for this move.
Return the added child node
"""
n = Node(move=m, parent=self, state=s)
self.untriedMoves.remove(m)
self.childNodes.append(n)
return n
def Update(self, result):
""" Update this node - one additional visit and result additional wins. result must be from the viewpoint of playerJustmoved.
"""
self.visits += 1
self.wins += result
def __repr__(self):
return "[M:" + str(self.move) + " W/V:" + str(self.wins) + "/" + str(
self.visits) + " U:" + str(self.untriedMoves) + "]"
def TreeToString(self, indent):
s = self.IndentString(indent) + str(self)
for c in self.childNodes:
s += c.TreeToString(indent + 1)
return s
def IndentString(self, indent):
s = "\n"
for i in range(1, indent + 1):
s += "| "
return s
def ChildrenToString(self):
s = ""
for c in self.childNodes:
s += str(c) + "\n"
return s
def UCT(rootstate, itermax, verbose=False):
""" Conduct a UCT search for itermax iterations starting from rootstate.
Return the best move from the rootstate.
Assumes 2 alternating players (player 1 starts), with game results in the range [0.0, 1.0]."""
rootnode = Node(state=rootstate)
for i in range(itermax):
node = rootnode
state = rootstate.Clone()
# Select
while node.untriedMoves == [] and node.childNodes != []: # node is fully expanded and non-terminal
node = node.UCTSelectChild()
state.DoMove(node.move)
# Expand
if node.untriedMoves != []: # if we can expand (i.e. state/node is non-terminal)
m = random.choice(node.untriedMoves)
state.DoMove(m)
node = node.AddChild(m, state) # add child and descend tree
# Rollout - this can often be made orders of magnitude quicker using a state.GetRandomMove() function
while state.GetMoves() != []: # while state is non-terminal
state.DoMove(random.choice(state.GetMoves()))
# Backpropagate
while node != None: # backpropagate from the expanded node and work back to the root node
node.Update(state.GetResult(
node.playerJustMoved)) # state is terminal. Update node with result from POV of node.playerJustMoved
node = node.parentNode
# Output some information about the tree - can be omitted
# if (verbose):
# print(rootnode.TreeToString(0))
# else:
# print(rootnode.ChildrenToString())
return sorted(rootnode.childNodes, key=lambda c: c.visits)[
-1].move # return the move that was most visited
def HumanPlayer(state):
moves = state.GetMoves()
while True:
try:
m = int(input("Your move " + str(moves) + " : "))
if m in moves:
return m
except ValueError:
pass
def RandomPlayer(state):
return random.choice(state.GetMoves())
def negamax(board, color, depth): # ##################################################
moves = board.GetMoves()
if not moves:
x = board.GetResult(board.playerJustMoved)
if x == 0.0:
print('negamax ERROR:')
print(board)
print(board.playerJustMoved)
print(board.curr, board.ended)
print(board.GetMoves())
raise ValueError
if x == 0.5:
return 0.0, None
if color == 1 and board.playerJustMoved == 1:
return 1.0, None
else:
return -1.0, None
if depth == 0:
return 0.0, None
v = float("-inf")
best_move = []
for m in moves:
new_board = board.Clone()
new_board.DoMove(m)
x, _ = negamax(new_board, -color, depth - 1)
x = - x
if x >= v:
if x > v:
best_move = []
v = x
best_move.append(m)
if depth >=8:
print(depth, v, best_move)
return v, best_move
def NegamaxPlayer(game):
best_moves = game.GetMoves()
if len(best_moves) != 9:
_, best_moves = negamax(game, 1, 4)
print(best_moves)
return random.choice(best_moves)
if __name__ == "__main__":
def main():
random.seed(123456789)
won = 0
lost = 0
draw = 0
for i in range(10):
# state = OXOState() # uncomment to play OXO
state = BigGameState()
move = 0
while (state.GetMoves() != []):
if state.playerJustMoved == 1:
# m = RandomPlayer(state)
m = UCT(rootstate=state, itermax=100, verbose=False)
else:
# m = UCT(rootstate=state, itermax=100, verbose=False)
# m = NegamaxPlayer(state)
m = HumanPlayer(state)
# m = RandomPlayer(state)
state.DoMove(m)
move += 1
print('Game ', i + 1, ', Move ', move, ':\n', state, sep='')
if state.GetResult(1) == 1.0:
won += 1
print("Player 1 wins!")
elif state.GetResult(1) == 0.0:
lost += 1
print("Player 2 wins!")
else:
draw += 1
print("Nobody wins!")
print('won', won, 'lost', lost, 'draw', draw)
start_time = time.perf_counter()
main()
total_time = time.perf_counter() - start_time
print('total_time', total_time)
关于python - 如何让我的 AI 算法玩 9 板井字游戏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55824246/
我正在关注 melon js tutorial .这是在我的 HUD.js 文件的顶部。 game.HUD = game.HUD || {} 我以前在其他例子中见过这个。 namespace.some
我刚刚制作了这个小游戏,用户可以点击。他可以看到他的点击,就像“cookieclicker”一样。 一切正常,除了一件事。 我尝试通过创建一个代码行变量来缩短我的代码,我重复了很多次。 documen
在此视频中:http://www.youtube.com/watch?v=BES9EKK4Aw4 Notch(我的世界的创造者)正在做他称之为“实时调试”的事情。他实际上是一边修改代码一边玩游戏,而不
两年前,我使用C#基于MonoGame编写了一款《俄罗斯方块》游戏,相关介绍可以参考【这篇文章】。最近,使用业余时间将之前的基于MonoGame的游戏开发框架重构了一下,于是,也就趁此机会将之前的《俄
1.题目 你和你的朋友,两个人一起玩 Nim 游戏: 桌子上有一堆石头。 你们轮流进行自己的回合, 你作为先手 。 每一回合,轮到的人拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。 假设
我正在创建平台游戏,有红色方 block (他们应该杀了我)和白色方 block (平台) 当我死时,我应该在当前级别的开始处复活。 我做了碰撞检测,但它只有在我移动时才有效(当我跳到红色方 bloc
因此,我正在处理(编程语言)中创建游戏突破,但无法弄清楚检查与 bat 碰撞的功能。 到目前为止,我写的关于与球棒碰撞的部分只是将球与底座碰撞并以相反的方向返回。目前,游戏是一种永无止境的现象,球只是
我试图让我的敌人射击我的玩家,但由于某种原因,子弹没有显示,也没有向玩家射击我什至不知道为什么,我什至在我的 window 上画了子弹 VIDEO bulls = [] runninggame = T
我正在尝试添加一个乒乓游戏框架。我希望每次球与 Racket 接触时球的大小都会增加。 这是我的尝试。第一 block 代码是我认为问题所在的地方。第二 block 是全类。 public class
我想知道 3D 游戏引擎编程通常需要什么样的数学?任何特定的数学(如向量几何)或计算算法(如快速傅立叶变换),或者这一切都被 DirectX/OpenGL 抽象掉了,所以不再需要高度复杂的数学? 最佳
我正在为自己的类(class)做一个霸气游戏,我一直在尝试通过添加许多void函数来做一些新的事情,但由于某种奇怪的原因,我的开发板无法正常工作,因为它说标识符“board”未定义,但是我有到目前为止
我在使用 mousePressed 和 mouseDragged 事件时遇到了一些问题。我正在尝试创建一款太空射击游戏,我希望玩家能够通过按下并移动鼠标来射击。我认为最大的问题是 mouseDragg
你好,我正在尝试基于概率实现战斗和准确性。这是我的代码,但效果不太好。 public String setAttackedPartOfBodyPercent(String probability) {
所以我必须实现纸牌游戏 war 。我一切都很顺利,除了当循环达到其中一张牌(数组列表)的大小时停止之外。我想要它做的是循环,直到其中一张牌是空的。并指导我如何做到这一点?我知道我的代码可以缩短,但我现
我正在做一个正交平铺 map Java 游戏,当我的船移动到 x 和 y 边界时,按方向键,它会停止移动(按预期),但如果我继续按该键,我的角色就会离开屏幕. 这是我正在使用的代码: @O
这里是 Ship、Asteroids、BaseShapeClass 类的完整代码。 Ship Class 的形状继承自 BaseShapeClass。 Asteroid类是主要的源代码,它声明了Gra
我正在开发这个随机数猜测游戏。在游戏结束时,我希望用户可以选择再次玩(或让其他人玩)。我发现了几个类似的线程和问题,但没有一个能够帮助我解决这个小问题。我很确定我可以以某种方式使用我的 while 循
我认为作为一个挑战,我应该编写一个基于 javascript 的游戏。我想要声音、图像和输入。模拟屏幕的背景(例如 640x480,其中包含我的所有图像)对于将页面的其余部分与“游戏”分开非常有用。我
我正在制作一个游戏,我将图标放在网格的节点中,并且我正在使用这个结构: typedef struct node{ int x,y; //coordinates for graphics.h
我正在研究我的游戏技能(主要是阵列)来生成敌人,现在子弹来击倒他们。我能够在测试时设置项目符号,但只有当我按下一个键(比方说空格键)并且中间没有间隔时才可见,所以浏览器无法一次接受那么多。 有没有什么
我是一名优秀的程序员,十分优秀!