2020年2月18日火曜日

開発環境

入門Goプログラミング (Nathan Youngman(著)、Roger Peppé(著)、吉川 邦夫(監修, 翻訳)、翔泳社)のUNIT 7(並行プログラミング)、LESSON 31(競合状態)の練習問題-2の解答を求めてみる。

コード

package main

import (
 "fmt"
 "image"
 "math/rand"
 "time"
)

type command int

const (
 right = command(0)
 left  = command(1)
 start = command(2)
 stop  = command(3)
)

type roverDriver struct {
 commandc chan command
}

func newRoverDriver() *roverDriver {
 r := &roverDriver{
  commandc: make(chan command),
 }
 go r.drive()
 return r
}

func (r *roverDriver) right() {
 r.commandc <- right
}
func (r *roverDriver) left() {
 r.commandc <- left
}
func (r *roverDriver) start() {
 r.commandc <- start
}
func (r *roverDriver) stop() {
 r.commandc <- stop
}
func (r *roverDriver) drive() {
 pos := image.Point{X: 0, Y: 0}
 direction := image.Point{X: 1, Y: 0}
 updateInterval := time.Second / 2
 nextMove := time.After(updateInterval)
 move := false
 for {
  select {
  case c := <-r.commandc:
   switch c {
   case right:
    direction = image.Point{
     X: -direction.Y,
     Y: direction.X,
    }
   case left:
    direction = image.Point{
     X: direction.Y,
     Y: -direction.X,
    }
   case start:
    if !move {
     fmt.Println("移動開始")
    }
    move = true
   case stop:
    if move {
     fmt.Println("移動停止")
    }
    move = false
   }
  case <-nextMove:
   if move {
    pos = pos.Add(direction)
    fmt.Printf("%vへ移動\n", pos)
   } else {
    fmt.Println("停止中")
   }
   nextMove = time.After(updateInterval)
  }
 }
}

func main() {
 rand.Seed(time.Now().UnixNano())
 r := newRoverDriver()
 for i := 0; i < 20; i++ {
  switch command(rand.Intn(4)) {
  case right:
   r.right()
  case left:
   r.left()
  case start:
   r.start()
  default:
   r.stop()
  }
  time.Sleep(time.Second)
 }
}

入出力結果(Zsh、PowerShell、Terminal)

% go build ./rover.go 
% ./rover 
移動開始
(1,0)へ移動
(1,-1)へ移動
(1,-2)へ移動
(1,-3)へ移動
(2,-3)へ移動
(3,-3)へ移動
(3,-2)へ移動
(3,-1)へ移動
(4,-1)へ移動
(5,-1)へ移動
移動停止
停止中
停止中
停止中
停止中
停止中
移動開始
(5,-2)へ移動
(5,-3)へ移動
(5,-4)へ移動
(5,-5)へ移動
移動停止
停止中
停止中
停止中
停止中
停止中
停止中
停止中
停止中
停止中
停止中
停止中
停止中
停止中
停止中
移動開始
(5,-4)へ移動
(5,-3)へ移動
(5,-2)へ移動
(5,-1)へ移動
移動停止
停止中
停止中
% ./rover
停止中
移動開始
(0,1)へ移動
(0,2)へ移動
(0,3)へ移動
(-1,3)へ移動
(-2,3)へ移動
(-2,2)へ移動
(-2,1)へ移動
(-2,0)へ移動
移動停止
停止中
停止中
停止中
停止中
停止中
停止中
移動開始
(-2,-1)へ移動
(-2,-2)へ移動
(-1,-2)へ移動
(0,-2)へ移動
(1,-2)へ移動
(2,-2)へ移動
(3,-2)へ移動
(4,-2)へ移動
(5,-2)へ移動
(6,-2)へ移動
(6,-1)へ移動
(6,0)へ移動
(7,0)へ移動
(8,0)へ移動
移動停止
停止中
停止中
停止中
停止中
移動開始
(8,1)へ移動
(8,2)へ移動
(8,3)へ移動
(8,4)へ移動
(9,4)へ移動
(10,4)へ移動
% 

0 コメント:

コメントを投稿