質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

2121閲覧

オセロ 

tamago0224

総合スコア71

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2015/04/06 08:15

ブログを見ながらswiftでオセロを作ったのですが、うまく動作しませんでした。
詳しい内容としては初期状態から黒の石を打つとうった場所に黒石が表示されなかったり、裏返されるべき石が裏返されなかったりといったことです。
文法的エラーは見当たらないのですが、わかる方はいませんか?

lang

1 2import UIKit 3 4 5 6 7let EMPTY = 0, WHITE_STONE = 2, BLACK_STONE = 1; 8 9 10 11 12let initboard = [//オセロボード上の初期状態 13 14 [0,0,0,0,0,0,0,0,0,0], 15 16 [0,0,0,0,0,0,0,0,0,0], 17 18 [0,0,0,0,0,0,0,0,0,0], 19 20 [0,0,0,0,0,0,0,0,0,0], 21 22 [0,0,0,0,2,1,0,0,0,0], 23 24 [0,0,0,0,1,2,0,0,0,0], 25 26 [0,0,0,0,0,0,0,0,0,0], 27 28 [0,0,0,0,0,0,0,0,0,0], 29 30 [0,0,0,0,0,0,0,0,0,0], 31 32 [0,0,0,0,0,0,0,0,0,0] 33 34] 35 36 37 38 39class OthelloView: UIView { 40 41 42 43 let white = UIColor.whiteColor().CGColor 44 45 let black = UIColor.blackColor().CGColor 46 47 let green = UIColor(red: 0.6,green: 1.0,blue: 0.2, alpha: 1.0).CGColor 48 49 var side: CGFloat = 0.0 50 51 var top: CGFloat = 0.0 52 53 var left: CGFloat = 0 54 55 56 57 override func drawRect(rect: CGRect){//描写時に呼び出されるメソッド 58 59 let context = UIGraphicsGetCurrentContext() 60 61 //各マスの枠線は白で太さ1.5ピクセル 62 63 CGContextSetStrokeColorWithColor(context,white) 64 65 CGContextSetLineWidth(context,1.5) 66 67 68 69 for y in 1...8 { 70 71 for x in 1...8 { 72 73 //マスの位置からマスのrect領域を計算 74 75 let rx = left + side * CGFloat(x-1) 76 77 let ry = top + side * CGFloat(y-1) 78 79 let rect = CGRectMake(rx, ry, side, side) 80 81 //まずは盤面を書くので塗りつぶし線を緑に決定 82 83 CGContextSetFillColorWithColor(context, green) 84 85 //塗りつぶし線、枠線を描写 86 87 CGContextFillRect(context,rect) 88 89 CGContextStrokeRect(context,rect) 90 91 92 93 if board[y][x] == BLACK_STONE { 94 95 //黒石が置いてあれば塗りつぶし色を黒にして円を描く 96 97 CGContextSetFillColorWithColor(context,black) 98 99 CGContextFillEllipseInRect(context,rect) 100 101 } else if board[y][x] == WHITE_STONE { 102 103 //白石が置いてあれば塗りつぶし色にして円を描く 104 105 CGContextSetFillColorWithColor(context,white) 106 107 CGContextFillEllipseInRect(context,rect) 108 109 } 110 111 } 112 113 } 114 115 } 116 117 118 119 override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { 120 121 //まずはプレイヤーが黒石を置けるかどうかを調べる 122 123 if let canBlack = canPlaced(board, stone: BLACK_STONE) { 124 125 //選択したマスの座標を取り出す 126 127 if let (x,y) = getPos(touches) { 128 129 //ひっくりかえせるか調べる 130 131 if let blackPlaces = flip(board,x: x,y: y,stone: BLACK_STONE) { 132 133 //ひっくり返す 134 135 putStone(blackPlaces,stone: BLACK_STONE) 136 137 //CPUのターンを進める 138 139 if let whitePlaces = cpuFlip(board, stone: WHITE_STONE) { 140 141 //ひっくり返す 142 143 putStone(whitePlaces,stone: WHITE_STONE) 144 145 } 146 147 } 148 149 } 150 151 152 153 } else { 154 155 //プレイヤーが石を置けないのでスキップしてCPUのターンを進める 156 157 if let whitePlaces = cpuFlip(board,stone: WHITE_STONE) { 158 159 putStone(whitePlaces,stone: WHITE_STONE) 160 161 } 162 163 } 164 165 upDateGames()//ゲームの勝敗を表示 166 167 setNeedsDisplay() 168 169 } 170 171 172 173 func upDateGames() { 174 175 let (free,black,white) = calcStones(board) 176 177 let canBlack = canPlaced(board,stone: BLACK_STONE) 178 179 let canWhite = canPlaced(board, stone: WHITE_STONE) 180 181 if free == 0 || (canBlack == nil && canWhite == nil) { 182 183 //開きますがない、または黒も白も置けない場合はゲーム終了 184 185 println("Game Over (Black: \(black) White: \(white)") 186 187 } 188 189 } 190 191 192 193 func getPos(touches: NSSet!) -> (Int,Int)? { 194 195 let touch = touches.anyObject() as UITouch 196 197 let point = touch.locationInView(self) 198 199 200 201 for y in 1...8 { 202 203 for x in 1...8 { 204 205 let rx = left + side * CGFloat(x-1) 206 207 let ry = top + side * CGFloat(y-1) 208 209 let rect = CGRectMake(rx,ry,side,side) 210 211 212 213 if CGRectContainsPoint(rect, point) { 214 215 return (x,y) 216 217 } 218 219 } 220 221 } 222 223 224 225 return nil 226 227 } 228 229 230 231 var board: [[Int]] 232 233 required init(coder aDecoder: NSCoder) { 234 235 let appFrame = UIScreen.mainScreen().applicationFrame 236 237 side = appFrame.size.width / 8 238 239 top = (appFrame.size.height - (side * 8)) / 2 240 241 board = initboard 242 243 super.init(coder: aDecoder) 244 245 } 246 247 248 249 func flipLine(board: [[Int]], x: Int, y: Int, stone: Int, dx: Int, dy: Int) -> [(Int,Int)] { 250 251 252 253 var flipLoop: (Int,Int) -> [(Int,Int)]? = {_ in nil}//ダミー関数オブジェクト 254 255 256 257 flipLoop = { (x: Int, y: Int) -> [(Int,Int)]? in 258 259 if board[y][x] == EMPTY { 260 261 return nil 262 263 } else if board[y][x] == stone { 264 265 return [] //再起の果てに自分の意思を発見 266 267 } else if var result = flipLoop(x+dx, y+dy) { //resultにはひっくり返す石の座標が入っている 268 269 result += [(x,y)]//nilでなければ相手の石を配列にして返す 270 271 return result 272 273 } 274 275 return nil 276 277 } 278 279 280 281 if let result = flipLoop(x + dx, y + dy) { 282 283 return result 284 285 } 286 287 return []//ひっくり返す必要のない場合ならから配列を返す。flipLineにはnilの戻り値はいらない 288 289 } 290 291 292 293 func flip(board: [[Int]], x: Int, y: Int, stone: Int) -> [(Int,Int)]? { 294 295 if board[y][x] != EMPTY {return nil} 296 297 298 299 var result: [(Int,Int)] = [] 300 301 302 303 result += flipLine(board,x: x,y: y,stone: stone,dx: 1,dy: 0) 304 305 result += flipLine(board,x: x,y: y,stone: stone,dx: -1,dy: 0) 306 307 result += flipLine(board,x: x,y: y,stone: stone,dx: 0,dy: 1) 308 309 result += flipLine(board,x: x,y: y,stone: stone,dx: 0,dy: -1) 310 311 result += flipLine(board,x: x,y: y,stone: stone,dx: 1,dy: 1) 312 313 result += flipLine(board,x: x,y: y,stone: stone,dx: -1,dy: -1) 314 315 result += flipLine(board,x: x,y: y,stone: stone,dx: 1,dy: -1) 316 317 result += flipLine(board,x: x,y: y,stone: stone,dx: -1,dy: 1) 318 319 320 321 if result.count > 0 { 322 323 return result 324 325 } else { 326 327 return nil 328 329 } 330 331 } 332 333 334 335 func canPlaced(board: [[Int]], stone: Int) -> [(Int,Int)]? { 336 337 var result: [(Int,Int)] = [] 338 339 340 341 for y in 1...8 { 342 343 for x in 1...8 { 344 345 if let temp = flip(board,x: x,y: y,stone: stone) { 346 347 result += [(x,y)] 348 349 } 350 351 } 352 353 } 354 355 356 357 if result.isEmpty { 358 359 return nil 360 361 } else { 362 363 return result 364 365 } 366 367 368 369 } 370 371 372 373 func cpuFlip(board: [[Int]], stone: Int) -> [(Int,Int)]? { 374 375 if let places = canPlaced(board, stone: stone) { 376 377 let (x,y) = places[ Int(arc4random()) % places.count] 378 379 return flip(board,x: x,y: y,stone: stone) 380 381 } 382 383 return nil 384 385 } 386 387 388 389 func calcStones(board: [[Int]]) -> (free: Int, black: Int, white: Int) { 390 391 var free = 0,white = 0,black = 0 392 393 for y in 1...8 { 394 395 for x in 1...8 { 396 397 switch board[y][x] { 398 399 case BLACK_STONE: black++ 400 401 case WHITE_STONE: white++ 402 403 default : free++ 404 405 } 406 407 } 408 409 } 410 411 return (free,black,white) 412 413 } 414 415 416 417 func putStone(places: [(Int,Int)], stone: Int) { 418 419 for (x,y) in places { 420 421 board[y][x] = stone 422 423 } 424 425 } 426 427 428 429}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

こんにちは。

OthelloViewのイニシャライザに識別子「required」が付与されていないなど、ソースコードに足りないものがありました。
下記にソースコードを記載させていただきます。ついででしたので、ゲームオーバーの際の処理(ゲームオーバーの判定、レーベル「label」の用意)を書き加えました。
あわせて、最下部にシミュレータのスクリーンショットを添付しました。

ご参考いただければ幸いです。

lang

1import UIKit 2 3let EMPTY = 0, BLACK_STONE = 1, WHITE_STONE = 2 4 5let initboard = [ 6 [0,0,0,0,0,0,0,0,0,0], 7 [0,0,0,0,0,0,0,0,0,0], 8 [0,0,0,0,0,0,0,0,0,0], 9 [0,0,0,0,0,0,0,0,0,0], 10 [0,0,0,0,2,1,0,0,0,0], 11 [0,0,0,0,1,2,0,0,0,0], 12 [0,0,0,0,0,0,0,0,0,0], 13 [0,0,0,0,0,0,0,0,0,0], 14 [0,0,0,0,0,0,0,0,0,0], 15 [0,0,0,0,0,0,0,0,0,0], 16] 17 18class OthelloView: UIView { 19 20 var board:[[Int]] = [] 21 let white = UIColor.whiteColor().CGColor 22 let black = UIColor.blackColor().CGColor 23 let green = UIColor(red:0.6, green:1.0, blue:0.2, alpha:1.0).CGColor 24 var side:CGFloat = 0.0 25 var top:CGFloat = 0.0 26 let left:CGFloat = 0 27 let label:UILabel = UILabel() 28 var gameOver = false 29 30 31 required init(coder aDecoder: NSCoder) { 32 let appFrame = UIScreen.mainScreen().applicationFrame 33 side = appFrame.size.width / 8 34 top = (appFrame.size.height - (side * 8)) / 2 35 board = initboard 36 37 super.init(coder:aDecoder) 38 39 label.text = "" 40 label.frame = CGRectMake(10, top / 2, appFrame.size.width, top / 2) 41 addSubview(label) 42 } 43 44 45 override func drawRect(rect: CGRect) { 46 let context = UIGraphicsGetCurrentContext() 47 CGContextSetStrokeColorWithColor(context, white) 48 CGContextSetLineWidth(context, 1.5) 49 50 for y in 1...8 { 51 for x in 1...8 { 52 let rx = left + side * CGFloat(x-1) 53 let ry = top + side * CGFloat(y-1) 54 let rect = CGRectMake(rx, ry, side, side) 55 CGContextSetFillColorWithColor(context, green) 56 CGContextFillRect(context, rect) 57 CGContextStrokeRect(context, rect) 58 59 if board[y][x] == BLACK_STONE { 60 CGContextSetFillColorWithColor(context, black) 61 CGContextFillEllipseInRect(context, rect) 62 } else if board[y][x] == WHITE_STONE { 63 CGContextSetFillColorWithColor(context, white) 64 CGContextFillEllipseInRect(context, rect) 65 } 66 } 67 } 68 } 69 70 override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { 71 if gameOver { 72 board = initboard 73 updateGame() 74 setNeedsDisplay() 75 return 76 } 77 if let canBlack = canPlaced(board, BLACK_STONE) { 78 if let (x, y) = getPos(touches) { 79 if let blackPlaces = flip(board, x, y, BLACK_STONE) { 80 putStones(blackPlaces, stone: BLACK_STONE) 81 if let whitePlaces = cpuFlip(board, WHITE_STONE) { 82 putStones(whitePlaces, stone: WHITE_STONE) 83 } 84 } 85 } 86 } else { 87 if let whitePlaces = cpuFlip(board, WHITE_STONE) { 88 putStones(whitePlaces, stone: WHITE_STONE) 89 } 90 } 91 updateGame() 92 setNeedsDisplay() 93 } 94 95 func getPos(touches: NSSet!) -> (Int, Int)? { 96 let touch = touches.anyObject() as UITouch 97 let point = touch.locationInView(self) 98 for y in 1...8 { 99 for x in 1...8 { 100 let rx = left + side * CGFloat(x-1) 101 let ry = top + side * CGFloat(y-1) 102 let rect = CGRectMake(rx, ry, side, side) 103 if CGRectContainsPoint(rect, point) { 104 return (x, y) 105 } 106 } 107 } 108 return nil 109 } 110 111 func putStones(places:[(Int, Int)], stone: Int) { 112 for (x, y) in places { 113 board[y][x] = stone 114 } 115 } 116 117 func updateGame() { 118 let (free, black, white) = calcStones(board) 119 let canBlack = canPlaced(board, BLACK_STONE) 120 let canWhite = canPlaced(board, WHITE_STONE) 121 if free == 0 || (canBlack == nil && canWhite == nil) { 122 label.text = "Game Over (Black:\(black) White:\(white))" 123 gameOver = true 124 } else { 125 label.text = "" 126 gameOver = false 127 } 128 } 129} 130 131func flip(board:[[Int]], x:Int, y:Int, stone:Int) -> [(Int, Int)]? { 132 if board[y][x] != EMPTY { return nil } 133 var result:[(Int, Int)] = [] 134 result += flipLine(board, x, y, stone, 1, 0) 135 result += flipLine(board, x, y, stone,-1, 0) 136 result += flipLine(board, x, y, stone, 0, 1) 137 result += flipLine(board, x, y, stone, 0,-1) 138 result += flipLine(board, x, y, stone, 1, 1) 139 result += flipLine(board, x, y, stone,-1,-1) 140 result += flipLine(board, x, y, stone, 1,-1) 141 result += flipLine(board, x, y, stone,-1, 1) 142 if result.count > 0 { 143 result += [(x, y)] 144 return result 145 } else { 146 return nil 147 } 148} 149 150func flipLine(board:[[Int]], x:Int, y:Int, stone:Int, dx:Int, dy:Int) -> [(Int, Int)] { 151 var flipLoop: (Int, Int) -> [(Int, Int)]? = { _ in nil } 152 flipLoop = { (x: Int, y: Int) -> [(Int, Int)]? in 153 if board[y][x] == EMPTY { 154 return nil 155 } else if board[y][x] == stone { 156 return [] 157 } else if var result = flipLoop(x+dx, y+dy) { 158 result += [(x, y)] 159 return result 160 } 161 return nil 162 } 163 if let result = flipLoop(x+dx, y+dy) { 164 return result 165 } 166 return [] 167} 168 169func canPlaced(board:[[Int]], stone: Int) -> [(Int, Int)]? { 170 var result:[(Int, Int)] = [] 171 for y in 1...8 { 172 for x in 1...8 { 173 if let res = flip(board, x, y, stone) { 174 result += [(x, y)] 175 } 176 } 177 } 178 if result.isEmpty { 179 return nil 180 } else { 181 return result 182 } 183} 184 185func cpuFlip(board:[[Int]], stone: Int) -> [(Int, Int)]? { 186 if let places = canPlaced(board, stone) { 187 let (x, y) = places[ Int(arc4random()) % places.count ] 188 return flip(board, x, y, stone) 189 } 190 return nil 191} 192 193func calcStones(board:[[Int]]) -> (free:Int, black:Int, white:Int) { 194 var free = 0, white = 0, black = 0 195 for y in 1...8 { 196 for x in 1...8 { 197 switch board[y][x] { 198 case BLACK_STONE: black++ 199 case WHITE_STONE: white++ 200 default: free++ 201 } 202 } 203 } 204 return (free, black, white) 205}

![イメージ説明]WIDTH:375

投稿2015/04/07 02:36

編集2015/04/08 01:56
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ちゃんと見たわけではありませんがinitboardで準備している配列が10x10のところがfor文で回しているところのindexが8になっているので8のところを10で置き換えればもしかしたらうまくいくんではないかと思います。

投稿2015/04/06 10:22

jollyjoester

総合スコア1585

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2015/04/07 02:17

こんにちは。 画面幅の8分の1をマス目の一辺にしている(side = appFrame.size.width / 8)ことから、マス目は8X8で設計していることがわかります。 オセロ盤の初期状態を10X10で定義しているのは、おそらく、後半のアルゴリズムで配列の範囲をチェックすることを省略しようとしているのではないかと思われます。 (横から失礼しました)
jollyjoester

2015/04/07 04:22

ご指摘ありがとうございます!そもそもオセロは8x8でやるものでそこ変えちゃいけませんでした(^^;;;
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問