Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 5x5 Go env #21

Merged
merged 18 commits into from
Sep 7, 2022
Merged

Add 5x5 Go env #21

merged 18 commits into from
Sep 7, 2022

Conversation

OkanoShinri
Copy link
Collaborator

cf. #18

@OkanoShinri
Copy link
Collaborator Author

しょうもないですけど5×5の碁ってなんかおもろいです

@OkanoShinri OkanoShinri changed the title Add 5*5 Go env Add 5x5 Go env Sep 6, 2022
tests/test_mini_go.py Outdated Show resolved Hide resolved
@sotetsuk
Copy link
Owner

sotetsuk commented Sep 6, 2022

再帰はたぶんですけど本質的に動的に深さが決まるので動かない気がします😭

@sotetsuk
Copy link
Owner

sotetsuk commented Sep 6, 2022

でもとりあえず動いてるものを書いてテスト作るという意味ではいいと思います!

@OkanoShinri
Copy link
Collaborator Author

再帰はたぶんですけど本質的に動的に深さが決まるので動かない気がします😭

😭😭😭
別の方法を探します。。。

@sotetsuk
Copy link
Owner

sotetsuk commented Sep 6, 2022

再帰はたぶんですけど本質的に動的に深さが決まるので動かない気がします😭

いや、動く。。。?ちょっと僕も調べてみます。
良かったらjax.jitで再帰が動くか試してほしいかも?

やっぱ動かないですね

@sotetsuk
Copy link
Owner

sotetsuk commented Sep 6, 2022

固定長forかなんかうまいこと行列演算考えるしかない。。。

@sotetsuk
Copy link
Owner

sotetsuk commented Sep 6, 2022

For以外のアイデアだと、囲み方のテンプレートというかパターンを全通り持っておいて、それと一致するかを判断するとか?
たとえば面積1の囲み方、面積2の囲み方、…、面積18x18の囲み方、みたいなのをすべて事前計算して持っておく。
5x5なら動くと思うが、19x19だと囲み方のパターンがいくつになるかわからない。

@OkanoShinri
Copy link
Collaborator Author

while(True)で再帰まがいのことができないかという案が出てきました
色々やってみます

@OkanoShinri
Copy link
Collaborator Author

@sotetsuk
そもそもwhileって大丈夫ですか?

@sotetsuk
Copy link
Owner

sotetsuk commented Sep 6, 2022

駄目ですね

@sotetsuk
Copy link
Owner

sotetsuk commented Sep 6, 2022

固定長じゃないと思われるので

Forもn=実行時最初に決まる値で以後不変、かつ長くない
じゃないと駄目です

@sotetsuk
Copy link
Owner

sotetsuk commented Sep 6, 2022

んーというか、まあループで実装はできると思いますがwhileでもforでも最大いくつで終わるのかわかってないと駄目です

@sotetsuk
Copy link
Owner

sotetsuk commented Sep 6, 2022

一旦ここは置いておいてもいいかもしれないです正直。他のところを先にやっても

@OkanoShinri
Copy link
Collaborator Author

しかし「囲まれているか」の判定って囲碁の根幹を成しているといいますか、合法手の判定にも使われますし不可欠な機能です。。。
あと囲み方を前もって保持しておくのはかなりキツイかと思います。。(入れ子の囲み方もあるので)

@OkanoShinri
Copy link
Collaborator Author

forで回せる回数の上限って流石に1000とか10000くらいは行けますよね…?
盤の石全て見ても高々361なので、事実上無限ループとみなして行けそうな気がしなくもないです

@sotetsuk
Copy link
Owner

sotetsuk commented Sep 6, 2022

んーどうだろうな。。。試してみないとなんとも。。。

@sotetsuk
Copy link
Owner

sotetsuk commented Sep 6, 2022

まあでもforでかけるならそれがいいです。

@sotetsuk
Copy link
Owner

sotetsuk commented Sep 6, 2022

再帰よりは

@OkanoShinri
Copy link
Collaborator Author

まさかbreak文も可変長と見なされたりするんですか…?

@OkanoShinri
Copy link
Collaborator Author

_is_surrounded()

  • 指定された点から始めて、上下左右に同じ色の石があれば候補に追加、空点があればFalseを返す
  • 候補が空になるまで繰り返し、空になったらTrueを返す
  • 繰り返し部分は十分大きな繰り返し数をとるforで実装
  • 候補の列は十分長い固定長配列

_is_surrounded_v2()

  • 全ての空点を候補に追加
  • 候補の末尾から始めて、上下左右に指定された色の石があれば空点にし、上下左右の空点を候補に追加
  • 候補が空になるまで繰り返し、最終的に残った指定色の石を囲まれた石とする
  • 繰り返し部分は十分大きな繰り返し数をとるforで実装
  • 候補の列は十分長い固定長配列

pgx/mini_go.py Outdated Show resolved Hide resolved
pgx/mini_go.py Outdated Show resolved Hide resolved
@OkanoShinri
Copy link
Collaborator Author

MiniGoStateの中身

  • board
    • 5x5のndarray(dtype=int), 0が黒石, 1が白石, 2が空点
  • turn
    • 1x1のndarray(dtype=int). 0始まりの経過ターン
  • agehama
    • 1x2のndarray(dtype=int). agehama[0]は先手が得たアゲハマ, agehama[1]は後手が得たアゲハマ
  • passed
    • 1x1のndarray(dtype=bool). 直前の行動がパスだとTrue
  • kou
    • 1x2のndarray(dtype=int). コウによる着手禁止点. 無ければ(-1, -1)

関数

  • init()
    • 初期化されたMiniGoStateを返す
  • show()
    • 可視化する
    • スクリーンショット 2022-09-07 235228
  • step()
    • 囲まれた石は囲碁のルールに従い取り除く
    • コウの判定も行う
    • ルール違反の手は負けとする
  • legal_actions()
    • 5x5のndarrayを返す. 石を置けるところをTrue, それ以外をFalseとしている

@sotetsuk
Copy link
Owner

sotetsuk commented Sep 7, 2022

ルール違反の手は負けとする

legal_action返してればルール違反負けはないって考えであってます?

@OkanoShinri
Copy link
Collaborator Author

ルール違反の手は負けとする

legal_action返してればルール違反負けはないって考えであってます?

大丈夫です!
一応ユーザーがlegal_action以外の手を打ってきた場合を想定しました

@OkanoShinri
Copy link
Collaborator Author

legal_actionが合法手になるテスト

import numpy as np

from pgx.mini_go import init, legal_actions, show, step

state = init()
done = False

while not done:
    actions = np.where(legal_actions(state))
    if actions[0].size == 0:
        a = None
    else:
        i = np.random.randint(0, actions[0].size)
        a = np.array([actions[0][i], actions[1][i]])
    state, _, done = step(state=state, action=a)

    if state.turn[0] > 300:
        break

@OkanoShinri
Copy link
Collaborator Author

これを数十回ほど回しましたがルール違反で終了することはありませんでした

@sotetsuk
Copy link
Owner

sotetsuk commented Sep 7, 2022

ルール違反の手は負けとする

legal_action返してればルール違反負けはないって考えであってます?

大丈夫です!
一応ユーザーがlegal_action以外の手を打ってきた場合を想定しました

了解です!
このときの挙動も後で考えますか🤔
でも例外投げるとかより即負け(一番大きい負の報酬を返す)でいい気がします!

@OkanoShinri
Copy link
Collaborator Author

明日の朝に見返して、問題なければマージします!

@OkanoShinri OkanoShinri merged commit e320b1e into main Sep 7, 2022
@OkanoShinri OkanoShinri deleted the okano/feat/mini_go branch September 7, 2022 19:29
@OkanoShinri OkanoShinri restored the okano/feat/mini_go branch September 11, 2022 11:03
@OkanoShinri OkanoShinri deleted the okano/feat/mini_go branch September 11, 2022 11:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants