前提・実現したいこと
初めてScannerを使ったのですがなぜか意図しない挙動になってしまいます。
というのはEnterを二回入力しなければ処理が進まない?感じなのでしょうか、
コンソールに描画されるはずのものが描画されません。
二回押すようにすりゃ済む話なのですがすっきりしないので誰かご指摘お願いいたします。
発生している問題・エラーメッセージ
リソース・リーク: 'scan' が閉じられることはありません
これはエラーというより警告みたいな感じなんですがこれが現れてから挙動がおかしいです。
該当のソースコード
java
1import java.util.ArrayList; 2import java.util.Arrays; 3import java.util.List; 4import java.util.Random; 5import java.util.Scanner; 6 7public class maruBatu { 8 9 static ArrayList<Integer> playerPositions = new ArrayList<Integer>(); 10 static ArrayList<Integer> cpuPositions = new ArrayList<Integer>(); 11 12 13 public static void main(String[] args) { 14 15 char [][] gameBoard = { 16 {' ', '|', ' ', '|', ' '}, 17 {'-', '+', '-', '+', '-'}, 18 {' ', '|', ' ', '|', ' '}, 19 {'-', '+', '-', '+', '-'}, 20 {' ', '|', ' ', '|', ' '} 21 }; 22 23 printGameBoard(gameBoard); 24 25 while(true) { 26 27 back:while(true) { 28 29 String crlf = System.getProperty("line.separator"); 30 31 Scanner scan = new Scanner(System.in); //入力の受付 32 System.out.println(crlf + "どこに置きますか?1~9で選んでください"); 33 int playerPos = scan.nextInt(); //ここの下の行 //System.inの入力結果をintに変換 34 if(playerPositions.contains(playerPos) || cpuPositions.contains(playerPos)) { //自分orCPUがとっていたら 35 System.out.println("そこはすでに置かれています。違う場所にしてください"); 36 printGameBoard(gameBoard); 37 break back; 38 } 39 40 placePiece(gameBoard, playerPos, "player"); 41 42 String result = checkWinner(); 43 if(result.length() > 0) { 44 System.out.println(result); 45 break; 46 } 47 48 Random rand = new Random(); 49 int cpuPos = rand.nextInt(9) + 1 ; 50 51 while(playerPositions.contains(cpuPos) || cpuPositions.contains(cpuPos)) { 52 cpuPos = rand.nextInt(9) + 1 ; 53 } 54 55 placePiece(gameBoard, cpuPos, "cpu"); 56 57 printGameBoard(gameBoard); 58 59 result =checkWinner(); 60 if(result.length() > 0) { 61 System.out.println(result); 62 break; 63 } 64 } 65 //break; ここにbreakを入れても同じような不具合になりましたのでコメントアウトしました。全く関係なさそうなのになぜでしょう? 66 } 67 68 } 69 70 public static void printGameBoard(char [][] gameBoard) { 71 for(char[] row : gameBoard) { //for each文 72 for(char c : row) { 73 System.out.print(c); 74 } 75 System.out.println(); 76 } 77 } 78 79 public static void placePiece(char[][] gameBoard, int pos, String user) { 80 81 char symbol = ' '; 82 83 if(user.equals("player")) { 84 symbol = 'X'; 85 playerPositions.add(pos); 86 }else if(user.equals("cpu")) { 87 symbol = 'O'; 88 cpuPositions.add(pos); 89 } 90 91 switch(pos) { 92 case 1: 93 gameBoard[0][0] = symbol; 94 break; 95 case 2: 96 gameBoard[0][2] = symbol; //[1]ではない 97 break; 98 case 3: 99 gameBoard[0][4] = symbol; 100 break; 101 case 4: 102 gameBoard[2][0] = symbol; 103 break; 104 case 5: 105 gameBoard[2][2] = symbol; 106 break; 107 case 6: 108 gameBoard[2][4] = symbol; 109 break; 110 case 7: 111 gameBoard[4][0] = symbol; 112 break; 113 case 8: 114 gameBoard[4][2] = symbol; 115 break; 116 case 9: 117 gameBoard[4][4] = symbol; 118 break; 119 default: 120 break; 121 122 } 123 } 124 125 public static String checkWinner() { 126 127 List topRow = Arrays.asList(1, 2, 3); //3要素 128 List midRow = Arrays.asList(4, 5, 6); 129 List botRow = Arrays.asList(7, 8, 9); 130 List leftCol = Arrays.asList(1, 4, 7); 131 List midCol = Arrays.asList(2, 5, 8); 132 List rightCol = Arrays.asList(3, 7, 9); 133 List cross1 = Arrays.asList(1, 5, 9); 134 List cross2 = Arrays.asList(3, 5, 7); 135 136 List<List> winning = new ArrayList<List>(); 137 winning.add(topRow); 138 winning.add(midRow); 139 winning.add(botRow); 140 winning.add(leftCol); 141 winning.add(midCol); 142 winning.add(rightCol); 143 winning.add(cross1); 144 winning.add(cross2); 145 146 for(List l : winning) { 147 if(playerPositions.containsAll(l)) { 148 return "YOU WIN!"; 149 }else if(cpuPositions.containsAll(l)) { 150 return "YOU LOSE"; 151 }else if(playerPositions.size() + cpuPositions.size() == 9) { 152 return "引き分け"; 153 } 154 } 155 156 return ""; 157 } 158 159} 160
試したこと
ググったらScannerを閉じればいいというのを見たのでscan.close()をコメントアウトしている場所(わかりにくくてすみません)
に書いたんですが、今度は別のエラーになったので消しました。
Exception in thread "main" どこに置きますか?1~9で選んでください java.util.NoSuchElementException at java.base/java.util.Scanner.throwFor(Scanner.java:937) at java.base/java.util.Scanner.next(Scanner.java:1594) at java.base/java.util.Scanner.nextInt(Scanner.java:2258) at java.base/java.util.Scanner.nextInt(Scanner.java:2212) at TicTacToe.main(TicTacToe.java:33)
でした。ちょっとこれは意味わかんないです。
補足情報(FW/ツールのバージョンなど)
自分で書いたコードなので読みにくいと思います。
ここはこうしたほうがいい、という事があればぜひ教えていただきたいです。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/30 13:06