有些人可能早些时候已经看过这个代码,我继续介绍它,现在我遇到了空指针和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);
}
}
}
Player类 public class Player实现Runnable { 卡[]手; String playerName; int strategyChosen; int playerNumber;
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;
}
}
游戏的目的是拥有所有相同价值牌。
我想知道是否有办法让线程按顺序打印,而且我也不明白为什么会出现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)
如果我要求太多,请道歉,但是我们将不胜感激。
答案 0 :(得分:1)
让我们看看以下代码:
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 - 运行起来很困惑,而“我不到一个数组的长度”,但这就是你的'得到了。一个潜在的问题是java数组从0开始,所以如果你的数组长度为5,那么它有0-4而不是1-5。如果您将数组声明为长度为6,则可能没问题。我没有挖掘你所有的代码来确定你是如何声明的。
所以循环从1到5;如果索引是4,则将该元素设置为null。因此,索引1,2,3和5处的值将尝试执行if语句的其他部分。如果它是5,那么你最好有一个数组,它将容纳索引6(长度为7),因为你有一个索引+ i进入数组。显然你没有,因为你的错误消息说6是一个超出范围的数组索引。
Java错误消息和堆栈跟踪是它最有用的两个特性。他们通常会告诉您问题是什么以及代码在何处被发现 - 这在编程领域并不普遍。如果您要使用Java编程,请学习相信您的错误消息,并学会阅读它们并从中获取信息作为解决问题的起点。
另外,我要说'索引'的使用令人困惑 - 除了我假设长度为+ 1且长度为1的拼写错误之外,它似乎仍然在循环中落后于'i'。如果你使用i迭代数组元素,那么我不能用来比较某些东西,看看你在哪里,下一步做什么等等,而不是使用另一个int?
最后,让我提醒您将数组的最后一个元素设置为null不会缩短数组。如果你有一个包含5个对象的数组并且你将最后一个设置为null,那么你在第5个元素中有一个null数组,而不是4个数组。我不知道你是否期望更改数组的长度,但你似乎有可能在这里给出了代码。