Scala.use(better)《tips431》Hexothello

f:id:shiorichannel:20210219132931p:plain
アプリケーション

》App15Window.scala

/*
 * Copyright (c) 2010-2013, KOTSUBU-chan and/or its affiliates.
 * Copyright (c) 1998, Atelier-AYA.
 * All rights reserved.
 */ 
package cherry.pie

// ----------------------------------------
import swing._
object App15Window extends MainFrame {
  val version =          App15Window
    .getClass.getName+": #1.0.03"
  // ----------------------------------------
  title = "15 puzzle"
  contents = new App15View(new Dimension(200,200))
  peer.setLocationRelativeTo(null)
}

// ----------------------------------------
class App15View(size: Dimension) extends FlowPanel {
  preferredSize = size
  new Publisher {
    import swing.event.MouseClicked
    reactions += {
      case MouseClicked(_,point,_,_,_) => update(point)
    }
  }.listenTo(mouse.clicks)

  import scala.collection.mutable.ArrayBuffer
  val tiles = ArrayBuffer.empty[Tile]
  0 to 14 foreach { i => tiles += Tile(i%4, i/4, i+1) }
  val nullTile = NullTile(3,3)
  tiles += nullTile
  shuffle(100)

  // ----------------------------------------
  import java.awt.Point
  def update(point: Point) =
    detect(point) match {
    case Some(tile: Tile) => move(tile); repaint
    case None =>
    }
  def detect(point: Point) = {
    tiles find { _.contains(point) } match {
    case Some(tile) =>
;print(tile)
      if (tile.isInContactWith(nullTile)) Some(tile) else None
    case None =>
    }
  }
  override def paintComponent(g: Graphics2D) =
    tiles foreach { _.paint(g) }

  def shuffle(count: Int) {
    val random = new scala.util.Random()
    0 to count foreach { e => move(tiles(random.nextInt(15))) }
  }
  def move(tile: Tile) = tile.swap(nullTile)
}

Apple.scala

/*
 * Copyright (c) 2010-2013, KOTSUBU-chan and/or its affiliates.
 * Copyright (c) 1998, Atelier-AYA.
 * All rights reserved.
 * ----------------------------------------
$ scalac -encoding "SJIS" -d bin src/{Apple,AppWindow,App15Window,Shape,Game}.scala
$ date; scala -cp bin cherry.pie.application
 * ----------------------------------------
2013年 11月 1日 金曜日 00時10分03秒 JST
----------------------------------------
cherry.pie.application$: #1.0.03
cherry.pie.appWindow$: #1.0.03
cherry.pie.Shape$: #1.0.03
cherry.pie.Game$: #1.0.03
----------------------------------------
(1,1)4(2,1)5(2,2)7(2,3)1(3,3)13(3,2)12(3,1)3(3,0)11(2,0)10(2,1)7(2,2)1(3,2)3(3,1)11(3,0)10(2,0)7(1,0)4(0,0)2(0,1)8(0,2)6(1,2)9(2,2)3(3,2)11(3,1)10(3,0)7(2,0)4(1,0)2(0,0)8(1,0)8(1,1)5(1,2)3(2,2)11(1,2)11(0,2)9(0,1)6(0,1)0(0,0)8(1,0)5(2,0)2(2,1)1(1,1)3(0,1)8(1,1)8(1,0)2(2,0)1(2,1)3(1,1)2(0,1)8(0,0)5(1,0)1(1,1)8(2,1)2(2,1)0(3,1)7(3,0)4(2,0)3(1,0)8(1,1)2(2,1)7(2,0)8(3,0)3(3,1)4(2,1)8(1,1)7(1,2)9(2,2)11(2,2)0(3,2)10(3,1)8(2,1)7(1,1)9(1,2)11(1,2)0(0,2)6(0,1)5(1,1)11(1,2)6(2,2)10(2,1)9(1,1)6(0,1)11(0,2)5(1,2)10(1,1)11(2,1)6(3,1)7(3,2)8(3,3)12(2,3)13(1,3)15(0,3)14(0,2)10(1,2)11(2,2)9(2,3)15(1,3)14(0,3)10(0,2)11(1,2)9(1,3)10(0,3)11(0,2)9(1,2)10(1,3)11(2,3)14(3,3)13(2,3)13(2,2)15(3,2)12(2,2)12(0,2)10(1,2)11(0,2)10(0,3)9(1,3)14(2,3)15(2,3)0(3,3)13$ 
 */
package cherry.pie

// ----------------------------------------
import swing._
object <span style="color: #ff5252">application</span> extends SimpleSwingApplication {
  val version =          application
    .getClass.getName+": #1.0.03"
  // ----------------------------------------
  println("-"*40)
  println(application.version)
  println(appWindow.version)
  println(Shape.version)
  println(Game.version)
  println("-"*40)
  def top = appWindow
  // ----------------------------------------
  App15Window.visible = true
}

》AppWindow.scala

/*
 * Copyright (c) 2010-2013, KOTSUBU-chan and/or its affiliates.
 * Copyright (c) 1998, Atelier-AYA.
 * All rights reserved.
 */ 
package cherry.pie

// ----------------------------------------
import swing._
object appWindow extends MainFrame {
  val version =          appWindow
    .getClass.getName+": #1.0.03"
  // ----------------------------------------
  title = "Honeycomb"
  contents = new View(new Dimension(250,250))
  peer.setLocationRelativeTo(null)
}

// ----------------------------------------
class View(size: Dimension) extends FlowPanel {
  preferredSize = size
  new Publisher {
    import swing.event.MouseClicked
    reactions += {
      case MouseClicked(_,p,_,_,_) => update(p)
    }
  }.listenTo(mouse.clicks)

  // ----------------------------------------
  val nullTile = NullTile(3,3)

  import scala.collection.mutable.ArrayBuffer
  val tiles = ArrayBuffer.empty[Tile]
  0 to 14 foreach { i => tiles += Tile(i%4, i/4, i+1) }
  tiles += nullTile
  shuffle(100)

  // ----------------------------------------
  import java.awt.Point
  def update(point: Point) = detect(point) match {
    case Some(tile: Tile) => move(tile); repaint
    case None =>
  }
  def detect(point: Point) = {
    tiles find { _.contains(point) } match {
    case Some(tile) =>
;print(tile)
      if (tile.isInContactWith(nullTile)) Some(tile) else None
    case None =>
    }
  }
  def shuffle(count: Int) {
    val random = new scala.util.Random
    0 to count foreach { _ => move(tiles(random.nextInt(15))) }
  }
  def move(tile: Tile) = tile.swap(nullTile)

  // ----------------------------------------
  override def paintComponent(g: Graphics2D) =
    tiles foreach { _.paint(g) }
}

》Game.scala

/*
 * Copyright (c) 2010-2013, KOTSUBU-chan and/or its affiliates.
 * Copyright (c) 1998, Atelier-AYA.
 * All rights reserved.
 */ 
package cherry.pie

// ----------------------------------------
object Game {
  val version =          Game
    .getClass.getName+": #1.0.03"
}

// ----------------------------------------
import java.awt._
object NullTile {
  def apply(x0: Int, y0: Int) = new Tile(x0, y0, 0) {
    override def paint(g: Graphics2D) =
      Rectangle(x*width, y*height, width, height)
        .paint(g, Color.lightGray)
  }
}
object Tile {
  def apply(x: Int, y: Int, n: Int) = new Tile(x, y, n)
}
class Tile(var x0: Int, var y0: Int, n: Int) {
  def x = x0
  def x_=(x: Int) { x0 = x }
  def y = y0
  def y_=(y: Int) { y0 = y }
  override def toString = "(%d,%d)%d" format (x,y,n)

  val (width, height) = (50, 50)
  val (px, py) = (x*width, y*height)
  val rect = Rectangle(px, py, width, height)
  val (dx, dy) = (4, 15)
  val symb = Symbol(n+"", px+dx, py+dy)

  def paint(g: Graphics2D) {
    rect.paint(g)
    symb.paint(g)
  }
  def contains(p: Point) = rect.contains(p)
  def isInContactWith(that: Tile) = {
    val a = x - that.x
    val b = y - that.y
    a*a + b*b == 1
  }
  def swap(that: Tile) = {
    val (this_x, this_y) = (x, y)
    this.move(that.x, that.y)
    that.move(this_x, this_y)
  }
  def move(x: Int, y: Int) {
    this.x = x; this.y = y
    val (px, py) = (x*width, y*height)
    rect.move(px, py)
    symb.move(px+dx, py+dy)
  }
}

》Shape.scala

/*
 * Copyright (c) 2010-2013, KOTSUBU-chan and/or its affiliates.
 * Copyright (c) 1998, Atelier-AYA.
 * All rights reserved.
 */ 
package cherry.pie

// ----------------------------------------
object Shape {
  val version =          Shape
    .getClass.getName+": #1.0.03,a"
}

// ----------------------------------------
import java.awt._
trait Shape {
  def paint(g: Graphics2D)
  def contains(p: Point): Boolean
  def move(x: Int, y: Int)
}

// ----------------------------------------
abstract class Geometry extends Shape {
  def paint(g: Graphics2D, fillColor: Color)
  def paint(g: Graphics2D): Unit = paint(g, defaultFillColor)
  def defaultFillColor = Color.white
  def defaultDrawColor = Color.black
}

// ----------------------------------------
object Rectangle {
  def apply(x: Int, y: Int, width: Int, height: Int) =
    (new Rectangle)(x, y, width, height)
}
class Rectangle extends Geometry {
  var peer: java.awt.Rectangle = _
  def apply(x: Int, y: Int, width: Int, height: Int) = {
    peer = new java.awt.Rectangle(x, y, width, height); this
  }
  def paint(g: Graphics2D, fillColor: Color) {
    val (x, y) = (peer.x, peer.y)
    val (width, height) = (peer.width, peer.height)
    g.setColor(fillColor)
    g.fillRect(x, y, width, height)
    g.setColor(defaultDrawColor)
    g.drawRect(x, y, width, height)
  }
  def contains(p: Point) = peer.contains(p)
  def move(x: Int, y: Int) = peer.setLocation(x,y)
}

// ----------------------------------------
object Symbol {
  def apply(s: String, x: Int, y: Int) = new Symbol(s, x, y)
}
class Symbol(s: String, var x: Int, var y: Int)
  extends Geometry {
  def paint(g: Graphics2D, fillColor: Color) {
    g.setColor(defaultDrawColor)
    g.drawString(s, x, y)
  }
  def contains(p: Point) = false
  def move(x: Int, y: Int) = { this.x = x; this.y = y }
}