2014-02-06 77 views
0

我不知道我做錯了什麼,但我在應用程序中收到「IndexOutOfBoundException」。這裏是我的代碼和logcat的:Android IndexOutOfBoundException

//代碼

public class GameView extends View { 

    private Context myContext; 
    private int scaledCardW; 
    private int scaledCardH; 
    private int screenH, screenW; 
    private List<Card> deck = new ArrayList<Card>(); 
    private List<Card> myHand = new ArrayList<Card>(); 
    private List<Card> oppHand = new ArrayList<Card>(); 
    private List<Card> discardPile = new ArrayList<Card>(); 

    private float scale; 
    private Paint blackPaint; 
    private int oppScore; 
    private int myScore; 

    private boolean myTurn; 

    private int movingCardIdx = -1; 
    private int movingX; 
    private int movingY; 

    private int validRank = 8; 
    private int validSuit = 0; 

    private Bitmap cardBack; 
    private Bitmap nextCardButton; 

    private ComputerPlayer computerPlayer = new ComputerPlayer(); 

    private int scoreThisHand = 0; 

    public GameView(Context context) { 
    super(context); 
    // TODO Auto-generated constructor stub 
    myContext = context; 

    scale = myContext.getResources().getDisplayMetrics().density; 

    blackPaint = new Paint(); 
    blackPaint.setAntiAlias(true); 
    blackPaint.setColor(Color.BLACK); 
    blackPaint.setStyle(Paint.Style.STROKE); 
    blackPaint.setTextAlign(Paint.Align.LEFT); 
    blackPaint.setTextSize(scale * 15); 

    //myTurn = new Random().nextBoolean(); 
    //myTurn = true; 
    } 

    @Override 
    public void onSizeChanged(int w, int h, int oldw, int oldh) 
    { 
     super.onSizeChanged(w, h, oldw, oldh); 
     screenH = h; 
     screenW = w; 

     initCards(); 

     dealCards(); 

     Bitmap tempBitmap = BitmapFactory.decodeResource(myContext.getResources(),R.drawable.card_back); 

     nextCardButton = BitmapFactory.decodeResource(myContext.getResources(), R.drawable.arrow_next); 

     scaledCardW = screenW/8; 
     scaledCardH = (int) (scaledCardW*1.28); 

     cardBack = Bitmap.createScaledBitmap(tempBitmap, scaledCardW,scaledCardH,false); 

     validRank = discardPile.get(0).getRank(); 
     validSuit = discardPile.get(0).getSuit(); 

     myTurn = new Random().nextBoolean(); 
     if(!myTurn) 
     { 
     makeComputerPlay(); 
     } 
    } 

    private void initCards() 
    { 
    for(int x = 0; x < 4; x++) 
    { 

     for(int y = 102; y < 115; y++) 
     { 
     int tempId = y + (x * 100); 

     Card tempCard = new Card(tempId); 
     int resourceId = getResources().getIdentifier("card"+ tempId, "drawable",myContext.getPackageName()); 

     Bitmap tempBitmap = BitmapFactory.decodeResource(myContext.getResources(),resourceId); 

     scaledCardW = screenW/8; 
     scaledCardH = (int) (scaledCardW*1.28); 
     Bitmap scaledBitmap = Bitmap.createScaledBitmap(tempBitmap,scaledCardW, scaledCardH, false); 


     tempCard.setBmp(scaledBitmap); 
     deck.add(tempCard); 
     } 

    } 

    } 

    private void drawCard(List<Card> handToDraw) 
    { 
    handToDraw.add(0,deck.get(0)); 
    deck.remove(0); 

    if(deck.isEmpty()) 
    { 
     for(int x = discardPile.size() -1; x > 0; x --) 
     { 
     deck.add(discardPile.get(0)); 
     discardPile.remove(0); 
     Collections.shuffle(deck, new Random()); 
     } 
    } 
    } 

    private void dealCards() 
    { 
    Collections.shuffle(deck, new Random()); 

    for(int y = 0; y < 7; y++) 
    { 
     drawCard(myHand); 
     //drawCard(oppHand); 
    } 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 

     //canvas.drawBitmap(deck.get(9).getBmp(), 80, 50,null); 

     canvas.drawText("Computer Score: " + oppScore, 10, blackPaint.getTextSize() + 10, blackPaint); 

     canvas.drawText("My Score: " + myScore, 10, (int)(screenH * 0.9) - blackPaint.getTextSize() - 10, blackPaint); 



     for (int i = 0; i < oppHand.size(); i++) 
     { 
     canvas.drawBitmap(cardBack, i*(scale*5), blackPaint.getTextSize()+(50*scale), null); 
     } 

     canvas.drawBitmap(cardBack, (screenW/2)-cardBack.getWidth()-10, (screenH/2)-(cardBack.getHeight()/2), null); 

     if (!discardPile.isEmpty()) 
     { 
     canvas.drawBitmap(discardPile.get(0).getBmp(),(screenW/2)+10,(screenH/2)-(cardBack.getHeight()/2), null); 
     } 


     for (int i = 0; i < myHand.size(); i++) { 
     if (i == movingCardIdx) 
     { 
      canvas.drawBitmap(myHand.get(i).getBmp(), 
       movingX, 
       movingY, 
       null); 
     } 
     else 
     { 
      canvas.drawBitmap 
      (myHand.get(i).getBmp(), 
      i*(scaledCardW+5), 
      screenH-blackPaint. 
      getTextSize()- 
      (50*scale), null); 
     } 
     } 


     if (myHand.size() > 7) 
     { 
     canvas.drawBitmap(nextCardButton, 
      screenW-nextCardButton.getWidth()-(30*scale),screenH-nextCardButton.getHeight()-scaledCardH-(90*scale),null); 
     } 

     for (int i = 0; i < myHand.size(); i++) 
     { 
     if (i == movingCardIdx) 
     { 
      canvas.drawBitmap(myHand.get(i).getBmp(),movingX, movingY, null); 
     } 
     else 
     { 
      if(i < 7) 
      { 
      canvas.drawBitmap(myHand.get(i).getBmp(),i*(scaledCardW+5),screenH-blackPaint.getTextSize()-(50*scale),null); 
      } 
     } 

     } 


     invalidate(); 

    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 

     int eventaction = event.getAction(); 
     int X = (int)event.getX(); 
     int Y = (int)event.getY(); 
     switch (eventaction) { 
     case MotionEvent.ACTION_DOWN: 

      if(myTurn) 
      { 
      for (int i = 0; i < 7; i++) 
      { 
       if (X > i*(scaledCardW+5) && X < i*(scaledCardW+5) + scaledCardW && Y > screenH-blackPaint.getTextSize()- (50*scale)) 
       { 
       movingCardIdx = i; 
       movingX = X-(int)(30*scale); 
       movingY = Y-(int)(70*scale); 
       } 
      } 

      } 
      break; 

     case MotionEvent.ACTION_MOVE: 
      movingX = X-(int)(30*scale); 
      movingY = Y-(int)(70*scale); 
      break; 

     case MotionEvent.ACTION_UP: 

      if (movingCardIdx > -1 && X > (screenW/2)-(100*scale) && X < (screenW/2)+(100*scale) && Y > (screenH/2)-(100*scale) && Y < (screenH/2)+(100*scale) && 
       (myHand.get(movingCardIdx).getRank() == 8 || myHand.get(movingCardIdx).getRank() == 
       validRank || myHand.get(movingCardIdx).getSuit() == validSuit)) 
      { 
      validRank = myHand.get(movingCardIdx).getRank(); 
      validSuit = myHand.get(movingCardIdx).getSuit(); 
      discardPile.add(0, myHand.get(movingCardIdx)); 
      myHand.remove(movingCardIdx); 

      if(myHand.isEmpty()) 
      { 
       endHand(); 
      } 
      else 
      { 
       if(validRank == 8) 
       { 
       showChooseSuitDialog(); 
       } 
       else 
       { 
       myTurn = false; 
       makeComputerPlay(); 
       } 
      } 
      } 
      movingCardIdx = -1; 

      if (movingCardIdx == -1 && myTurn && X > (screenW/2)-(100*scale) && X < (screenW/2)+(100*scale) && 
       Y > (screenH/2)-(100*scale) && Y < (screenH/2)+(100*scale)) 
      { 
      if (checkForValidDraw()) 
      { 
       drawCard(myHand); 
      } 
      else 
      { 
       Toast.makeText(myContext, "You have a valid play.", Toast.LENGTH_SHORT).show(); 
      } 

      } 

      if (myHand.size() > 7 && X > screenW-nextCardButton.getWidth()-(30*scale) && Y > screenH-nextCardButton.getHeight()-scaledCardH- (90*scale) && 
       Y < screenH-nextCardButton.getHeight()-scaledCardH - (60*scale)) 
      { 
      Collections.rotate(myHand, 1); 
      } 

      break; 
     } 

     invalidate(); 
     return true; 
    } 

    private void showChooseSuitDialog() 
    { 
    final Dialog chooseSuitDialog = new Dialog(myContext); 
    chooseSuitDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 
    chooseSuitDialog.setContentView(R.layout.choose_suit_dialog); 
    final Spinner suitSpinner = (Spinner)chooseSuitDialog.findViewById(R.id.suitSpinner); 
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(myContext, R.array.suits,android.R.layout.simple_spinner_item); 
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
    suitSpinner.setAdapter(adapter); 
    Button okButton = (Button) chooseSuitDialog.findViewById(R.id.okButton); 
    okButton.setOnClickListener(new View.OnClickListener() 
     { 
     @Override 
     public void onClick(View view) 
     { 
     validSuit = (suitSpinner. 
      getSelectedItemPosition()+1)*100; 
     String suitText = ""; 
     if (validSuit == 100) { 
     suitText = "Diamonds"; 
     } else if (validSuit == 200) { 
     suitText = "Clubs"; 
     } else if (validSuit == 300) { 
     suitText = "Hearts"; 
     } else if (validSuit == 400) { 
     suitText = "Spades"; 
     } 
     chooseSuitDialog.dismiss(); 
     Toast.makeText(myContext,"You chose " + suitText,Toast.LENGTH_SHORT).show(); 

     myTurn = false; 
     makeComputerPlay(); 
     } 
     }); 

    chooseSuitDialog.show(); 
    } 

    private boolean checkForValidDraw() 
    { 
    boolean canDraw = true; 
    for (int i = 0; i < myHand.size(); i++) 
    { 
     int tempId = myHand.get(i).getId(); 
     int tempRank = myHand.get(i).getRank(); 
     int tempSuit = myHand.get(i).getSuit(); 
     if (validSuit == tempSuit || validRank == tempRank || tempId == 108 || tempId == 208 ||tempId == 308 || tempId == 408) 
     { 
     canDraw = false; 
     } 
    } 
    return canDraw; 
    } 


    private void makeComputerPlay() 
    { 
    int tempPlay = 0; 
    while (tempPlay == 0) 
    { 
     tempPlay = computerPlayer.makePlay(oppHand,validSuit, validRank); 
     if (tempPlay == 0) 
     { 
     drawCard(oppHand); 
     } 
    } 
    if (tempPlay == 108 || tempPlay == 208 || tempPlay == 308 || tempPlay == 408) 
    { 
     validRank = 8; 
     validSuit = computerPlayer.chooseSuit(oppHand); 
     String suitText = ""; 
     if (validSuit == 100) 
     { 
     suitText = "Diamonds"; 
     } 
     else if (validSuit == 200) 
     { 
     suitText = "Clubs"; 
     } 
     else if (validSuit == 300) 
     { 
     suitText = "Hearts"; 
     } 
     else if (validSuit == 400) 
     { 
     suitText = " Spades"; 
     } 
     Toast.makeText(myContext, "Computer chose " + suitText, Toast.LENGTH_SHORT).show(); 
    } 
    else 
    { 
     validSuit = Math.round((tempPlay/100) * 100); 
     validRank = tempPlay - validSuit; 
    } 

    for (int i = 0; i < oppHand.size(); i++) 
    { 

     Card tempCard = oppHand.get(i); 
     if (tempPlay == tempCard.getId()) 
     { 
     discardPile.add(0, oppHand.get(i)); 
     oppHand.remove(i); 
     } 
    } 

    if(oppHand.isEmpty()) 
    { 
     endHand(); 
    } 

    myTurn = true; 

    } 



    private void updateScores() 
    { 
    for (int i = 0; i < myHand.size(); i++) 
    { 
     oppScore += myHand.get(i).getScoreValue(); 
     scoreThisHand += myHand.get(i).getScoreValue(); 
    } 

    for (int i = 0; i < oppHand.size(); i++) 
    { 
     myScore += oppHand.get(i).getScoreValue(); 
     scoreThisHand += oppHand.get(i).getScoreValue(); 
    } 

    } 

    private void endHand() 
    { 
    final Dialog endHandDialog = new Dialog(myContext); 
    endHandDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 
    endHandDialog.setContentView(R.layout.end_hand_dialog); 
    updateScores(); 
    TextView endHandText = (TextView)endHandDialog.findViewById(R.id.endHandText); 
    if (myHand.isEmpty()) 
    { 
     if(myScore >= 300) 
     { 
     endHandText.setText("You reached " + myScore + " points. You won! Would you like to play again?"); 

     } 
     else 
     { 
     endHandText.setText("You went out and got " + scoreThisHand + " points!"); 
     } 
    } 
    else if (oppHand.isEmpty()) 
    { 
     if (oppScore >= 300) 
     { 
     endHandText.setText("The computer reached " + oppScore + " points. Sorry, you lost. Would you like to play again?"); 
     } 
     else 
     { 
     endHandText.setText("The computer went out and got " + scoreThisHand + " points."); 
     } 
    } 


    Button nextHandButton = (Button)endHandDialog.findViewById(R.id.nextHandButton); 
    if (oppScore >= 300 || myScore >= 300) 
    { 
     nextHandButton.setText("New Game"); 
    } 

    nextHandButton.setOnClickListener(new View.OnClickListener() 
     { 
     @Override 
     public void onClick(View view) 
     { 
     if (oppScore >= 300 || myScore >= 300) 
     { 
     myScore = 0; 
     oppScore = 0; 
     } 

     initNewHand(); 
     endHandDialog.dismiss(); 
     } 

     }); 

    endHandDialog.show(); 

    } 

    private void initNewHand() { 
    // TODO Auto-generated method stub 

    scoreThisHand = 0; 
    if (myHand.isEmpty()) 
    { 
     myTurn = true; 
    } 
    else if (oppHand.isEmpty()) 
    { 
     myTurn = false; 
    } 
    deck.addAll(discardPile); 
    deck.addAll(myHand); 
    deck.addAll(oppHand); 

    discardPile.clear(); 
    myHand.clear(); 
    oppHand.clear(); 

    dealCards(); 
    drawCard(discardPile); 

    validSuit = discardPile.get(0).getSuit(); 
    validRank = discardPile.get(0).getRank(); 

    if (!myTurn) 
    { 
     makeComputerPlay(); 
    } 
    } 


} 

//這裏是我的logcat

error opening trace file: No such file or directory (2) 
GC_FOR_ALLOC freed 34K, 7% free 2395K/2572K, paused 88ms, total 91ms 
Grow heap (frag case) to 3.210MB for 770432-byte allocation 
GC_FOR_ALLOC freed <1K, 6% free 3147K/3328K, paused 100ms, total 100ms 
GC_CONCURRENT freed <1K, 6% free 3265K/3448K, paused 23ms+25ms, total 186ms 
Emulator without GPU emulation detected. 
GC_CONCURRENT freed 245K, 11% free 3524K/3920K, paused 75ms+53ms, total 455ms 
WAIT_FOR_CONCURRENT_GC blocked 194ms 
GC_CONCURRENT freed 315K, 12% free 3673K/4160K, paused 14ms+29ms, total 370ms 
WAIT_FOR_CONCURRENT_GC blocked 212ms 
GC_CONCURRENT freed 287K, 11% free 3853K/4320K, paused 78ms+64ms, total 441ms 
WAIT_FOR_CONCURRENT_GC blocked 182ms 
GC_CONCURRENT freed 352K, 12% free 3961K/4500K, paused 9ms+28ms, total 363ms 
WAIT_FOR_CONCURRENT_GC blocked 243ms 
GC_CONCURRENT freed 314K, 11% free 4105K/4600K, paused 98ms+61ms, total 434ms 
WAIT_FOR_CONCURRENT_GC blocked 234ms 
GC_CONCURRENT freed 352K, 12% free 4268K/4820K, paused 9ms+80ms, total 530ms 
WAIT_FOR_CONCURRENT_GC blocked 215ms 
GC_FOR_ALLOC freed 193K, 12% free 4244K/4820K, paused 68ms, total 70ms 
Grow heap (frag case) to 4.583MB for 316480-byte allocation 
GC_FOR_ALLOC freed <1K, 12% free 4553K/5132K, paused 147ms, total 147ms 
Shutting down VM 
threadid=1: thread exiting with uncaught exception (group=0x40a71930) 
FATAL EXCEPTION: main 
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0 
     at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251) 
     at java.util.ArrayList.get(ArrayList.java:304) 
     at com.example.crazyeights.GameView.onSizeChanged(GameView.java:94) 
     at android.view.View.setFrame(View.java:14094) 
     at android.view.View.layout(View.java:14006) 
     at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 
     at android.view.View.layout(View.java:14008) 
     at android.view.ViewGroup.layout(ViewGroup.java:4373) 
     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1663) 
     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1521) 
     at android.widget.LinearLayout.onLayout(LinearLayout.java:1434) 
     at android.view.View.layout(View.java:14008) 
     at android.view.ViewGroup.layout(ViewGroup.java:4373) 
     at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 
     at android.view.View.layout(View.java:14008) 
     at android.view.ViewGroup.layout(ViewGroup.java:4373) 
     at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1892) 
     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1711) 
     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:989) 
     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4351) 
     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749) 
     at android.view.Choreographer.doCallbacks(Choreographer.java:562) 
     at android.view.Choreographer.doFrame(Choreographer.java:532) 
     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735) 
     at android.os.Handler.handleCallback(Handler.java:725) 
     at android.os.Handler.dispatchMessage(Handler.java:92) 
     at android.os.Looper.loop(Looper.java:137) 
     at android.app.ActivityThread.main(ActivityThread.java:5041) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:511) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
     at dalvik.system.NativeStart.main(Native Method) 
Sending signal. PID: 929 SIG: 9 
GC_FOR_ALLOC freed 38K, 8% free 2395K/2576K, paused 326ms, total 332ms 
Grow heap (frag case) to 3.210MB for 770432-byte allocation 
GC_FOR_ALLOC freed <1K, 6% free 3147K/3332K, paused 79ms, total 79ms 
GC_CONCURRENT freed <1K, 6% free 3273K/3452K, paused 31ms+29ms, total 163ms 
Emulator without GPU emulation detected. 
+1

您是否嘗試過使用調試器? –

+0

因此,您希望有人閱讀並理解超過500個loc的相應視圖的第94行中出現的問題,而無需實際指出它是哪一行? – keyboardsurfer

+0

我該怎麼做?我是Android – user3279003

回答

2

在你onSizeChanged(),你get(0)訪問discardPile的第一要素,但discardPile是空的。

+0

我應該在第一張卡上添加一張卡元件? – user3279003

+0

我不知道。有太多的代碼需要通讀才能弄清楚爲什麼「get(0)」調用首先出現在那裏。也許'isEmpty()'檢查會有所幫助。 – laalto

+0

問題是,如果丟棄堆中沒有卡片,您希望屏幕看起來如何。 –

相關問題