当我递归调用它时,为啥我的函数返回以前的值而不是新的值?
Posted
技术标签:
【中文标题】当我递归调用它时,为啥我的函数返回以前的值而不是新的值?【英文标题】:Why does my function return the previous values and not the new ones when I call it recursively?当我递归调用它时,为什么我的函数返回以前的值而不是新的值? 【发布时间】:2015-03-03 15:26:22 【问题描述】:我要编写一个启动 2 个玩家的程序,将相同的 Dealer 实例传递给每个玩家。在为每位玩家发完 7 张牌后,每位牌手应将自己的牌张列表打印到一个文本文件中,该文件的名称为玩家编号。
现在,在多米诺骨牌游戏中,两个玩家不能拥有相同的牌,即(玩家 1:2,4 AND 玩家 2:4,2)。
我使用了一个 2D 布尔标志数组来检查这一点,但是每当我打印出列表时,我发现 2 个或更多玩家拥有相同的牌。另外,请注意,我必须使用线程来代表玩家。
这是我的 Player 的运行方法。每个玩家应该得到 7 张牌。
public synchronized void run()
try
try (PrintWriter writer = new PrintWriter("Player " + player + ".txt"))
for (int i = 0; i < 7; i++)
Random r = new Random();
int a = r.nextInt(6);
int b = r.nextInt(6);
System.out.println("Player " + player + " is requesting a tile");
DominoTiles dealt = dealer.deal(a, b);
tiles[i] = dealt;
writer.println("Requesting Player " + player + ": ");
writer.println("Side 1 = " + tiles[i].getSide1() + " Side 2 = " + tiles[i].getSide2());
catch (InterruptedException ex)
Logger.getLogger(Player.class.getName()).log(Level.SEVERE, null, ex);
catch (FileNotFoundException ex)
Logger.getLogger(Player.class.getName()).log(Level.SEVERE, null, ex);
这是我的经销商的交易方法。如果它进入 if 块,我将返回该函数,如果它进入 else if 块,则再次调用它。问题是,我返回使函数进入 else if 块的值!
public synchronized DominoTiles deal(int a, int b) throws FileNotFoundException, InterruptedException
DominoTiles dealt = new DominoTiles(a, b);
System.out.println("Dealer is dealing");
if ((count < 28 && check[a][b] == false))
System.out.println("Checking " + a + " " + b + ": " + check[a][b]);
System.out.println(a + " " + b + " has been dealt");
check[a][b] = true;
check[b][a] = true;
System.out.println("Checking now : " + check[a][b]);
count++;
System.out.println("Count = " + count);
else if ((count < 28 && (check[a][b] == true || check[b][a] == true)) || (check[b][a] == true))
System.out.println("I tried to deal the same again!" + a + " " + b + " and it was " + check[a][b] + " " + check[b][a
]);
int c = r.nextInt(7);
int d = r.nextInt(7);
deal(c, d);
else
System.out.println("All tiles have been dealt");
System.exit(0);
return dealt;
【问题讨论】:
如果您可以制作这个可执行文件,我们将更容易找出问题所在。执行时更容易阅读代码 可执行文件是指显示输出吗? 你为什么要递归,而不仅仅是循环?调用System.exit(0)
的方法通常是个坏主意。改为抛出异常...
反正你的方法不好。你不应该试图解决这个问题——让它死掉。为每个可能的图块创建一个List
,然后通过将其从列表中删除来从该列表中随机绘制一个图块。这是可能的,因为您可以使用的图块数量非常有限。
这是一种更好的算法。 shuffled = Collections.shuffle(range_of_numbers) player_1_random_1 = shuffled[0], player_1_random_2 = shuffled[1], player_2_random_1 = random.select(Collections.shuffle(shuffled.slice(2,n))), player_2_random_2 = random.select(Collections .shuffle(range_of_numbers_without_player_2_random_1));顺便说一句,这不是 java 代码......只是伪代码,但你明白了。不需要丑陋的循环或递归。
【参考方案1】:
这是因为您没有将递归调用 deal() 的结果分配给 dealt 变量。
修复:
public synchronized DominoTiles deal(int a, int b) throws FileNotFoundException, InterruptedException
DominoTiles dealt = new DominoTiles(a, b);
System.out.println("Dealer is dealing");
if ((count < 28 && check[a][b] == false))
System.out.println("Checking " + a + " " + b + ": " + check[a][b]);
System.out.println(a + " " + b + " has been dealt");
check[a][b] = true;
check[b][a] = true;
System.out.println("Checking now : " + check[a][b]);
count++;
System.out.println("Count = " + count);
else if ((count < 28 && (check[a][b] == true || check[b][a] == true)) || (check[b][a] == true))
System.out.println("I tried to deal the same again!" + a + " " + b + " and it was " + check[a][b] + " " + check[b][a
]);
int c = r.nextInt(7);
int d = r.nextInt(7);
dealt = deal(c, d);
else
System.out.println("All tiles have been dealt");
System.exit(0);
return dealt;
【讨论】:
【参考方案2】:您需要将任何可以跨线程使用的变量标记为 volatile 以供初学者使用。
【讨论】:
方法是同步的——这不是问题 同步只使变量在进入和退出同步阶段时被“刷新”。根据样本,我没有看到足够好的可靠保证。可能是这样,但我们没有看到全貌。以上是关于当我递归调用它时,为啥我的函数返回以前的值而不是新的值?的主要内容,如果未能解决你的问题,请参考以下文章
如何按显示的值而不是数据字段值对gridview列进行排序/过滤
为啥我的 Python 函数打印一个值但返回 None? [关闭]