開発環境
- macOS Catalina - Apple (OS)
- Emacs (Text Editor)
- Windows 10 Pro (OS)
- Visual Studio Code (Text Editor)
- Go (プログラミング言語)
入門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 コメント:
コメントを投稿