有些人可能之前看过这段代码,我继续了它,现在我遇到了空指针和indexOutOfBound异常的问题。有时会出现索引越界错误,具体取决于玩家数量或手牌大小。
这是代码,主要的 CardGame 类
public class CardGame
{
static Player[] players;
static int handSize;
static Queue<Card>[] playingDeckArray;
static int playersNum;
public static void main(String[] args){
Scanner reader = new Scanner(System.in);
System.out.println( "\nHello, how many players would you like" );
playersNum = Integer.parseInt(Checks.userInputCheck( "\\d" ));
System.out.println( "\nHow many cards should each player begin with" );
int handSize = Integer.parseInt(Checks.userInputCheck( "\\d" ));
System.out.println( "\nWhich strategy would you like to use 1 or 2" );
int strategy = Integer.parseInt(Checks.userInputCheck( "[12]$" ));
Logger.createDeck( playersNum, handSize );
makePlayers( playersNum, handSize, strategy );
makePlayingDecks( playersNum );
dealInitialHand( playersNum, players, handSize );
makePlayerOutputs();
//Player.startPauseThread();
for ( int i = 0; i < players.length; i++){
logInitialHand(players[i]);
}
for ( int i = 0; i < players.length; i++){
isWinner( players[i]);
}
for ( int i = 0; i < players.length; i++){
new Thread(players[i]).start();
}
}
private static void makePlayers( int noPlayers, int noCardsInHand, int strategyChosen){
players = new Player[noPlayers];
for( int i = 0; i < noPlayers; i++){
players[i] = new Player( strategyChosen, noCardsInHand, i+1 );
players[i].fillHand();
}
}
private static void dealInitialHand(int noPlayers, Player[] players, int noCardsInHand ){
System.out.println( "\nPlease enter the name of the deck file" );
File theDeck = new File (Checks.userInputCheck( "deckfile.txt" ) );
int line = 0;
try{
Scanner fileScanner = new Scanner( theDeck );
for( int h = 0; h < noCardsInHand; h++){
for( int p = 0; p < noPlayers; p++){
line = Integer.parseInt( fileScanner.nextLine() );
players[p].setHand( line, h );
}
}
for( int t = 0; t < noCardsInHand; t++){
for( int i = 0; i < playingDeckArray.length; i++ ){
line = Integer.parseInt( fileScanner.nextLine() );
playingDeckArray[i].add( new Card(line) );
}
}
}catch (Exception e) {
e.printStackTrace();
}
seePlayerHands();
}
private static void makePlayingDecks( int noPlayers ){
playingDeckArray = new Queue[noPlayers];
for( int i = 0; i < playingDeckArray.length; i++ ){
playingDeckArray[i] = new ConcurrentLinkedQueue<Card>();
System.out.println( playingDeckArray[i] );
}
}
private static void seePlayerHands(){
for ( int i = 0; i < players.length; i++){
System.out.println( players[i].getPlayerName() + "'s hand is currently" );
players[i].seeHand();
}
}
private static void makePlayerOutputs(){
for ( int i = 0; i < players.length; i++){
Logger.createPlayerOutputs( players[i].getPlayerName());
}
}
private static void logInitialHand( Player player ){
Logger.addToOutput( player.getPlayerName(), ( player.getPlayerName() + "'s initial hand is " ) );
Logger.addToOutput( player.getPlayerName(), player.getHand() );
}
private static void isWinner( Player player ){
boolean winner = true;
int first = player.hand[0].getCardValue();
for (Card element : player.hand) {
if (element.getCardValue() != first) {
winner = false;
}
}
if ( winner == true ){
Logger.addToOutput( player.getPlayerName(), ( player.getPlayerName() + " has won the game with a hand of " ) );
Logger.addToOutput( player.getPlayerName(), player.getHand() );
System.out.println( player.getPlayerName() + " has won the game with a hand of " );
player.seeHand();
System.exit(0);
}
}
}
玩家类 公共(public)类 Player 实现 Runnable { 卡牌[]手牌; 字符串玩家名称; int策略选择; int 玩家编号;
private boolean running = true;
private boolean paused = false;
public void setPaused( boolean paused ){
this.paused = paused;
}
public void run(){
while(running){
if(!paused){
synchronized(this){
playGame();
}
}
}
}
private void playGame(){
synchronized(this){
switch(strategyChosen){
case 1 : playStratOne();
break;
case 2 : playStratTwo();
break;
}
}
}
public static void startPauseThread(){
Thread add = new Thread( pauseInputThread );
add.start();
}
static Thread pauseInputThread = new Thread(){
private boolean running = true;
private boolean paused = false;
public void run(){
while(running){
if(!paused){
for(;;){
System.out.println("FEED ME");
Scanner reader = new Scanner(System.in);
String result = Checks.userInputCheck( "[pPrR]$" );
if( result == "p" ){
for ( int i = 0; i < CardGame.players.length; i++ ){
CardGame.players[i].setPaused( true );
}
}
}
}
}
}
};
private Player(){
}
private int getPlayerNumber(){
return playerNumber;
}
public Player( int strategy, int cardsInHand, int playerNumber ){
hand = new Card[cardsInHand];
strategyChosen = strategy;
this.playerNumber = playerNumber;
playerName = "Player " + playerNumber;
}
public String getPlayerName(){
return playerName;
}
public void fillHand(){
for ( int i = 0; i < hand.length; i++){
hand[i] = new Card(0);
}
}
public void setHand( int value, int index ){
hand[index].setCardValue( value );
}
public void seeHand(){
for ( int i = 0; i < hand.length; i++){
System.out.println( hand[i].getCardValue() );
}
}
public String getHand(){
String result = "";
for ( int i = 0; i < hand.length; i++ ){
result = result + hand[i].getCardValue() + " \n" ;
}
return result;
}
public int getHandValue( Card card ){
return card.getCardValue();
}
private void playStratOne(){
System.out.println("fuck");
}
private void playStratTwo(){
synchronized(this){
int index = 0;
System.out.println( getPlayerName() + " discards a " + hand[index].getCardValue() + " to deck " + playerNumber );
CardGame.playingDeckArray[playerNumber-1].add( new Card( getHandValue(hand[index])));
for( int i = 1; i < hand.length+1; i++){
if ( index == hand.length-1 ){
hand[index] = null;
}else{
hand[index] = hand[index+i];
index = index + i;
}
}
if ( playerNumber == 1){
System.out.println( getPlayerName() + " draws a " + ((CardGame.playingDeckArray[playerNumber + CardGame.playersNum - 2].poll()).getCardValue()) + " from deck " + ( CardGame.playersNum ) );
hand[index] = CardGame.playingDeckArray[playerNumber + CardGame.playersNum - 2].poll();
}else{
System.out.println( getPlayerName() + " draws a " + (( CardGame.playingDeckArray[playerNumber - 2].poll()).getCardValue()) + " from deck " + ( playerNumber - 1 ) );
hand[index] = CardGame.playingDeckArray[playerNumber - 2].poll();
}
System.out.println(getPlayerName()+ "'s hand is ");
seeHand();
for( int i = 0; i < CardGame.playingDeckArray.length; i++ ){
}
checkWinner();
}
}
private void checkWinner(){
boolean winner = true;
int first = hand[0].getCardValue();
for (Card element : hand) {
if (element.getCardValue() != first) {
winner = false;
}
}
if ( winner == true ){
Logger.addToOutput( getPlayerName(), ( getPlayerName() + " has won the game with a hand of " ) );
Logger.addToOutput( getPlayerName(), getHand() );
System.out.println( getPlayerName() + " has won the game with a hand of " );
seeHand();
System.exit(0);
}
}
}
卡片类
public class Card
{
int cardValue;
private Card(){
}
public Card( int value ){
cardValue = value;
}
public void setCardValue( int value ){
cardValue = value;
}
public int getCardValue(){
return cardValue;
}
public int getCardValue( Card card ){
return cardValue;
}
}
游戏的目标是拥有一手所有相同值(value)的牌。
我想知道是否有办法让线程按顺序打印,而且我不明白为什么会出现 nullPointers 和 IndexOutOfBounds 错误
这是手牌大小为 2 的 2 人游戏的结果
Hello, how many players would you like
2
Thank You
How many cards should each player begin with
2
Thank You
Which strategy would you like to use 1 or 2
2
Thank You
The deck has been created
It is called deckfile.txt
Please enter the name of the deck file
deckfile.txt
Thank You
Player 1's hand is currently
1
3
Player 2's hand is currently
2
3
Player 1 discards a 1 to deck 1
Player 1 draws a 4 from deck 2
Player 2 discards a 2 to deck 2
Player 1's hand is
Player 2 draws a 4 from deck 1
3
2
Player 2's hand is
3
1
Player 1 discards a 3 to deck 1
Player 2 discards a 3 to deck 2
Player 1 draws a 2 from deck 2
Player 2 draws a 1 from deck 1
Player 1's hand is
2
3
Player 1 discards a 2 to deck 1
Player 2's hand is
1
3
Player 2 discards a 1 to deck 2
Player 2 draws a 2 from deck 1
Player 2's hand is
3
这会产生 nullPointer 异常,当我玩手大小为 5 的 5 人游戏时
Player 1's hand is currently
1
4
1
4
8
Player 2's hand is currently
2
1
1
3
1
Player 3's hand is currently
3
2
10
6
2
Player 4's hand is currently
3
7
5
8
6
Player 5's hand is currently
4
4
2
1
4
Player 1 discards a 1 to deck 1
Player 2 discards a 2 to deck 2
Player 5 discards a 4 to deck 5
Player 3 discards a 3 to deck 3
Player 4 discards a 3 to deck 4
我收到了indexOutOfBounds异常
Exception in thread "Thread-8" Exception in thread "Thread-9" java.lang.ArrayIndexOutOfBoundsException: 6
at Player.playStratTwo(Player.java:132)
at Player.playGame(Player.java:38)
at Player.run(Player.java:27)
at java.lang.Thread.run(Thread.java:722)
抱歉,如果我要求太多,但我们将不胜感激。
最佳答案
让我们看一下下面的代码:
int index = 0;
System.out.println( getPlayerName() + " discards a " + hand[index].getCardValue() + " to deck " + playerNumber );
CardGame.playingDeckArray[playerNumber-1].add( new Card( getHandValue(hand[index])));
for( int i = 1; i < hand.length+1; i++){
if ( index == hand.length-1 ){
hand[index] = null;
}else{
hand[index] = hand[index+i];
index = index + i;
}
}
因此,在 for 循环开始时,index 的值不能不同于 0。
如果 hand.length 是 5,那么循环将从 1 到 5 - 当“i 比数组长度多不到一”时运行会很困惑,但这就是你的意思我得到了。这样做的一个潜在问题是 java 数组从 0 开始,因此如果数组长度为 5,那么它有卡片 0-4,而不是 1-5。如果您将数组声明为长度为 6,这可能没问题。我还没有深入研究您的所有代码来确定您是如何声明它的。
因此循环从 1 运行到 5;如果索引为 4,则将该元素设置为 null。因此索引 1、2、3 和 5 处的值将尝试执行 if 语句的其他部分。如果是 5,那么您最好有一个可容纳索引 6(长度为 7)的数组,因为数组中有一个索引 + i。显然你没有,因为你的错误消息说 6 是数组索引越界。
Java 错误消息和堆栈跟踪是其两个最有用的功能。他们最常告诉您问题是什么以及在代码中的哪个位置发现问题——这在编程世界中并不通用。如果您要使用 Java 编程,请学会信任错误消息,并学会阅读它们并从中获取信息,作为解决问题的起点。
此外,我要说的是,“index”的使用令人困惑——在循环中,它似乎在“i”后面保留了一个计数,除了我认为是长度 + 1 和长度 - 1 的拼写错误之外.如果你使用 i 来遍历数组元素,那么我不能用来与某些东西进行比较来查看你在哪里,下一步要做什么等等,而不是使用另一个 int 吗?
最后,我要提醒您,将数组的最后一个元素设置为 null 不会缩短数组。如果您有一个包含 5 个对象的数组,并且将最后一个对象设置为 null,那么您将得到一个第 5 个元素为 null 的数组,而不是一个包含 4 个对象的数组。我不知道您是否期望数组的长度发生变化,但看来您确实在这里给出了代码。
关于java - 如何让线程按顺序打印java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20447589/