├── tools
├── tentool
│ ├── .gitignore
│ ├── utils
│ │ ├── check.go
│ │ ├── routines.go
│ │ ├── gzfile.go
│ │ ├── tracker.go
│ │ ├── interactive_writer.go
│ │ ├── options.go
│ │ ├── file.go
│ │ ├── interactive_tracker.go
│ │ ├── donwload_test.go
│ │ └── scheduler.go
│ ├── stats
│ │ ├── test_data
│ │ │ ├── list.js
│ │ │ ├── scc20120404.html
│ │ │ ├── list_old.js
│ │ │ ├── sca.log
│ │ │ ├── sce20180101.html
│ │ │ ├── scf.log
│ │ │ ├── scb.log
│ │ │ ├── scd.log
│ │ │ └── sce.log
│ │ ├── urls.go
│ │ ├── cmd_yadisk.go
│ │ ├── parse_test.go
│ │ ├── parse.go
│ │ └── index.go
│ ├── export.json
│ ├── logs
│ │ ├── parse.go
│ │ ├── cmd_status.go
│ │ ├── cmd_collect.go
│ │ ├── cmd_yadisk.go
│ │ ├── id_test.go
│ │ ├── cmd_remove_index.go
│ │ ├── cmd_get.go
│ │ ├── parse_test.go
│ │ └── test_data
│ │ │ └── scc.html
│ ├── Makefile
│ ├── main.go
│ └── README.md
└── tools.go
├── vendor
├── github.com
│ ├── spf13
│ │ ├── pflag
│ │ │ ├── .gitignore
│ │ │ ├── .golangci.yaml
│ │ │ ├── .editorconfig
│ │ │ ├── .travis.yml
│ │ │ └── LICENSE
│ │ └── cobra
│ │ │ ├── .mailmap
│ │ │ ├── MAINTAINERS
│ │ │ ├── .gitignore
│ │ │ ├── command_notwin.go
│ │ │ ├── Makefile
│ │ │ ├── command_win.go
│ │ │ └── .golangci.yml
│ ├── c2h5oh
│ │ └── datasize
│ │ │ ├── .travis.yml
│ │ │ ├── .gitignore
│ │ │ └── LICENSE
│ ├── golang
│ │ └── protobuf
│ │ │ ├── AUTHORS
│ │ │ ├── CONTRIBUTORS
│ │ │ └── LICENSE
│ ├── facebookgo
│ │ ├── stackerr
│ │ │ ├── readme.md
│ │ │ ├── .travis.yml
│ │ │ └── license
│ │ └── stack
│ │ │ ├── .travis.yml
│ │ │ └── license
│ ├── stretchr
│ │ └── testify
│ │ │ ├── require
│ │ │ ├── require_forward.go.tmpl
│ │ │ ├── require.go.tmpl
│ │ │ ├── forward_requirements.go
│ │ │ ├── doc.go
│ │ │ └── requirements.go
│ │ │ ├── assert
│ │ │ ├── assertion_format.go.tmpl
│ │ │ ├── assertion_forward.go.tmpl
│ │ │ ├── errors.go
│ │ │ ├── forward_assertions.go
│ │ │ ├── yaml
│ │ │ │ ├── yaml_fail.go
│ │ │ │ ├── yaml_custom.go
│ │ │ │ └── yaml_default.go
│ │ │ └── doc.go
│ │ │ └── LICENSE
│ ├── dnovikoff
│ │ └── tempai-core
│ │ │ ├── yaku
│ │ │ ├── types.go
│ │ │ ├── fu.go
│ │ │ ├── limit.go
│ │ │ ├── resources.go
│ │ │ ├── limit_string.go
│ │ │ ├── fu_string.go
│ │ │ ├── win.go
│ │ │ ├── context.go
│ │ │ ├── rules_predefined.go
│ │ │ ├── rules.go
│ │ │ └── yakuman_string.go
│ │ │ ├── hand
│ │ │ ├── calc
│ │ │ │ ├── tags.go
│ │ │ │ ├── meld_debug.go
│ │ │ │ ├── meld_stack.go
│ │ │ │ ├── counter_block.go
│ │ │ │ ├── meld.go
│ │ │ │ ├── options.go
│ │ │ │ ├── meld_kokushi.go
│ │ │ │ └── melds.go
│ │ │ ├── tempai
│ │ │ │ ├── debug.go
│ │ │ │ └── type_string.go
│ │ │ └── effective
│ │ │ │ ├── sort.go
│ │ │ │ └── effective.go
│ │ │ ├── base
│ │ │ ├── wind.go
│ │ │ └── wind_string.go
│ │ │ ├── tile
│ │ │ └── type.go
│ │ │ ├── compact
│ │ │ ├── packed_masks.go
│ │ │ ├── test_generator.go
│ │ │ ├── constants.go
│ │ │ ├── generator.go
│ │ │ └── totals.go
│ │ │ ├── score
│ │ │ ├── rules.go
│ │ │ └── rules_prefefined.go
│ │ │ └── LICENSE
│ ├── satori
│ │ └── go.uuid
│ │ │ ├── .travis.yml
│ │ │ └── LICENSE
│ ├── inconshreveable
│ │ └── mousetrap
│ │ │ ├── trap_others.go
│ │ │ ├── README.md
│ │ │ └── trap_windows.go
│ ├── davecgh
│ │ └── go-spew
│ │ │ └── LICENSE
│ └── pmezard
│ │ └── go-difflib
│ │ └── LICENSE
├── go.uber.org
│ └── multierr
│ │ ├── .gitignore
│ │ ├── .codecov.yml
│ │ ├── Makefile
│ │ ├── LICENSE.txt
│ │ └── README.md
├── google.golang.org
│ └── protobuf
│ │ ├── internal
│ │ ├── editiondefaults
│ │ │ ├── editions_defaults.binpb
│ │ │ └── defaults.go
│ │ ├── flags
│ │ │ ├── proto_legacy_enable.go
│ │ │ ├── proto_legacy_disable.go
│ │ │ └── flags.go
│ │ ├── genid
│ │ │ ├── name.go
│ │ │ ├── doc.go
│ │ │ ├── wrappers.go
│ │ │ ├── map_entry.go
│ │ │ ├── empty_gen.go
│ │ │ ├── goname.go
│ │ │ ├── field_mask_gen.go
│ │ │ ├── source_context_gen.go
│ │ │ ├── any_gen.go
│ │ │ ├── duration_gen.go
│ │ │ └── timestamp_gen.go
│ │ ├── impl
│ │ │ ├── codec_unsafe.go
│ │ │ ├── enum.go
│ │ │ ├── pointer_unsafe_opaque.go
│ │ │ └── bitmap.go
│ │ ├── protolazy
│ │ │ └── pointer_unsafe.go
│ │ ├── editionssupport
│ │ │ └── editions.go
│ │ ├── pragma
│ │ │ └── pragma.go
│ │ ├── descopts
│ │ │ └── options.go
│ │ ├── set
│ │ │ └── ints.go
│ │ └── encoding
│ │ │ └── text
│ │ │ └── doc.go
│ │ ├── encoding
│ │ └── prototext
│ │ │ └── doc.go
│ │ ├── runtime
│ │ └── protoiface
│ │ │ └── legacy.go
│ │ ├── proto
│ │ ├── proto_reflect.go
│ │ ├── proto_methods.go
│ │ ├── reset.go
│ │ ├── wrappers.go
│ │ └── proto.go
│ │ ├── cmd
│ │ └── protoc-gen-go
│ │ │ └── internal_gengo
│ │ │ └── init_opaque.go
│ │ ├── PATENTS
│ │ └── LICENSE
└── gopkg.in
│ ├── yaml.v2
│ ├── .travis.yml
│ ├── NOTICE
│ ├── writerc.go
│ └── LICENSE.libyaml
│ └── yaml.v3
│ └── NOTICE
├── .gitignore
├── network
├── examples
│ ├── logs1.zip
│ ├── logs2.zip
│ ├── logs3.zip
│ ├── logs4.zip
│ ├── doc.txt
│ ├── f5182_2018-01-22_12_36_49.log
│ └── second.log
├── auth_test.go
├── xml_connection_debug.go
├── auth.go
└── xml_connection.go
├── cmd
├── pimboo-server
│ ├── example.gif
│ ├── main.go
│ ├── README.md
│ └── game
│ │ └── player.go
└── tenhou-proxy
│ └── README.md
├── tbase
├── lobby_test.go
├── seed.go
├── helpers.go
├── sex.go
├── draw.go
├── yaku_test.go
├── meld.go
├── meld_test.go
├── lobby.go
├── meld_encode.go
└── called.go
├── log
├── xml_test.go
├── controller.go
├── null_controller.go
├── test_data
│ ├── README.txt
│ └── example.txt
└── info_test.go
├── parser
├── parse.go
├── seed.go
├── agari.go
├── node_reader.go
└── xml.go
├── server
├── xml_test.go
├── examples_test.go
└── controller.go
├── Makefile
├── .github
└── workflows
│ └── ci.yaml
├── go.mod
├── README.md
├── LICENSE
├── util
├── async_writer.go
└── util_test
│ └── xml_test.go
├── client
└── controller.go
├── protoc.mk
└── proto
└── stats
└── stats.proto
/tools/tentool/.gitignore:
--------------------------------------------------------------------------------
1 | /tenhou
2 | /export
3 | /gobin
--------------------------------------------------------------------------------
/vendor/github.com/spf13/pflag/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/*
2 |
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /gobin
2 | /build
3 | /coverage.txt
4 | /database
--------------------------------------------------------------------------------
/vendor/go.uber.org/multierr/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | cover.html
3 | cover.out
4 | /bin
5 |
--------------------------------------------------------------------------------
/network/examples/logs1.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dnovikoff/tenhou/HEAD/network/examples/logs1.zip
--------------------------------------------------------------------------------
/network/examples/logs2.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dnovikoff/tenhou/HEAD/network/examples/logs2.zip
--------------------------------------------------------------------------------
/network/examples/logs3.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dnovikoff/tenhou/HEAD/network/examples/logs3.zip
--------------------------------------------------------------------------------
/network/examples/logs4.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dnovikoff/tenhou/HEAD/network/examples/logs4.zip
--------------------------------------------------------------------------------
/cmd/pimboo-server/example.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dnovikoff/tenhou/HEAD/cmd/pimboo-server/example.gif
--------------------------------------------------------------------------------
/vendor/github.com/spf13/pflag/.golangci.yaml:
--------------------------------------------------------------------------------
1 | linters:
2 | disable-all: true
3 | enable:
4 | - nolintlint
5 |
--------------------------------------------------------------------------------
/tools/tools.go:
--------------------------------------------------------------------------------
1 | // +build tools
2 |
3 | package tools
4 |
5 | import (
6 | _ "github.com/golang/protobuf/protoc-gen-go"
7 | )
8 |
--------------------------------------------------------------------------------
/tools/tentool/utils/check.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import "log"
4 |
5 | func Check(err error) {
6 | if err == nil {
7 | return
8 | }
9 | log.Fatal(err)
10 | }
11 |
--------------------------------------------------------------------------------
/tools/tentool/stats/test_data/list.js:
--------------------------------------------------------------------------------
1 | list([
2 | {file:'sca20180926.log.gz',size:35919},
3 | {file:'sca20180927.log.gz',size:33557},
4 | {file:'sca20180928.log.gz',size:35839}
5 | ]);
6 |
--------------------------------------------------------------------------------
/tools/tentool/stats/test_data/scc20120404.html:
--------------------------------------------------------------------------------
1 | 12:20 | 13 | 四鳳東喰赤- | 牌譜 | チーター(+46.0) 里中静流(+2.0) Lask&Yu(-19.0) きょうしろう(-29.0)
2 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dnovikoff/tenhou/HEAD/vendor/google.golang.org/protobuf/internal/editiondefaults/editions_defaults.binpb
--------------------------------------------------------------------------------
/vendor/github.com/spf13/cobra/.mailmap:
--------------------------------------------------------------------------------
1 | Steve Francia
2 | Bjørn Erik Pedersen
3 | Fabiano Franz
4 |
--------------------------------------------------------------------------------
/vendor/github.com/c2h5oh/datasize/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 |
3 | language: go
4 | go:
5 | - 1.4
6 | - 1.5
7 | - 1.6
8 | - 1.7
9 | - 1.8
10 | - 1.9
11 | - tip
12 |
13 | script:
14 | - go test -v
15 |
--------------------------------------------------------------------------------
/vendor/github.com/golang/protobuf/AUTHORS:
--------------------------------------------------------------------------------
1 | # This source code refers to The Go Authors for copyright purposes.
2 | # The master list of authors is in the main Go distribution,
3 | # visible at http://tip.golang.org/AUTHORS.
4 |
--------------------------------------------------------------------------------
/vendor/github.com/golang/protobuf/CONTRIBUTORS:
--------------------------------------------------------------------------------
1 | # This source code was written by the Go contributors.
2 | # The master list of contributors is in the main Go distribution,
3 | # visible at http://tip.golang.org/CONTRIBUTORS.
4 |
--------------------------------------------------------------------------------
/tbase/lobby_test.go:
--------------------------------------------------------------------------------
1 | package tbase
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | )
8 |
9 | func TestLobbyEncode(t *testing.T) {
10 | assert.Equal(t, "0841", RulesDzjanso.String())
11 | }
12 |
--------------------------------------------------------------------------------
/tools/tentool/export.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "search": "^2023.+$",
4 | "file": "export/logs2023_part.zip"
5 | },
6 | {
7 | "search": "^([0-9]{4}).+$",
8 | "file": "export/logs$1.zip"
9 | }
10 | ]
--------------------------------------------------------------------------------
/vendor/github.com/spf13/cobra/MAINTAINERS:
--------------------------------------------------------------------------------
1 | maintainers:
2 | - spf13
3 | - johnSchnake
4 | - jpmcb
5 | - marckhouzam
6 | inactive:
7 | - anthonyfok
8 | - bep
9 | - bogem
10 | - broady
11 | - eparis
12 | - jharshman
13 | - wfernandes
14 |
--------------------------------------------------------------------------------
/vendor/github.com/facebookgo/stackerr/readme.md:
--------------------------------------------------------------------------------
1 | stackerr [](http://travis-ci.org/facebookgo/stackerr)
2 | ========
3 |
4 | Documentation: https://godoc.org/github.com/facebookgo/stackerr
5 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/require/require_forward.go.tmpl:
--------------------------------------------------------------------------------
1 | {{.CommentWithoutT "a"}}
2 | func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) {
3 | if h, ok := a.t.(tHelper); ok { h.Helper() }
4 | {{.DocInfo.Name}}(a.t, {{.ForwardedParams}})
5 | }
6 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl:
--------------------------------------------------------------------------------
1 | {{.CommentFormat}}
2 | func {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool {
3 | if h, ok := t.(tHelper); ok { h.Helper() }
4 | return {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}})
5 | }
6 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl:
--------------------------------------------------------------------------------
1 | {{.CommentWithoutT "a"}}
2 | func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool {
3 | if h, ok := a.t.(tHelper); ok { h.Helper() }
4 | return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}})
5 | }
6 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/pflag/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | indent_size = 4
7 | indent_style = space
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.go]
12 | indent_style = tab
13 |
--------------------------------------------------------------------------------
/tools/tentool/stats/test_data/list_old.js:
--------------------------------------------------------------------------------
1 | list([
2 | {file:'2018/sca20180101.log.gz',size:79921},
3 | {file:'2018/sca20180102.log.gz',size:60186},
4 | {file:'2018/sca20180103.log.gz',size:63155},
5 | {file:'2018/scf20180924.html.gz',size:1984}
6 | ]);
7 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/require/require.go.tmpl:
--------------------------------------------------------------------------------
1 | {{ replace .Comment "assert." "require."}}
2 | func {{.DocInfo.Name}}(t TestingT, {{.Params}}) {
3 | if h, ok := t.(tHelper); ok { h.Helper() }
4 | if assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return }
5 | t.FailNow()
6 | }
7 |
--------------------------------------------------------------------------------
/tbase/seed.go:
--------------------------------------------------------------------------------
1 | package tbase
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/score"
5 | "github.com/dnovikoff/tempai-core/tile"
6 | )
7 |
8 | type Seed struct {
9 | RoundNumber int
10 | Honba score.Honba
11 | Sticks score.RiichiSticks
12 | Dice [2]int
13 | Indicator tile.Instance
14 | }
15 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | go:
4 | - "1.4.x"
5 | - "1.5.x"
6 | - "1.6.x"
7 | - "1.7.x"
8 | - "1.8.x"
9 | - "1.9.x"
10 | - "1.10.x"
11 | - "1.11.x"
12 | - "1.12.x"
13 | - "1.13.x"
14 | - "1.14.x"
15 | - "tip"
16 |
17 | go_import_path: gopkg.in/yaml.v2
18 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/encoding/prototext/doc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package prototext marshals and unmarshals protocol buffer messages as the
6 | // textproto format.
7 | package prototext
8 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/flags/proto_legacy_enable.go:
--------------------------------------------------------------------------------
1 | // Copyright 2018 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build protolegacy
6 | // +build protolegacy
7 |
8 | package flags
9 |
10 | const protoLegacy = true
11 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/flags/proto_legacy_disable.go:
--------------------------------------------------------------------------------
1 | // Copyright 2018 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build !protolegacy
6 | // +build !protolegacy
7 |
8 | package flags
9 |
10 | const protoLegacy = false
11 |
--------------------------------------------------------------------------------
/tools/tentool/stats/test_data/sca.log:
--------------------------------------------------------------------------------
1 | L1001 | 15:24 | 三般南喰赤- | ケモさん(+95.0) セネ.(-27.0) 鰐吉(-68.0)
2 | L1001 | 15:35 | 四般南喰赤- | 鰐吉(+57.0) NoName(+25.0) ケモさん(-23.0) セネ.(-59.0)
3 | L1002 | 21:00 | 四般南喰赤- | 小宇(+66.0) exia_ang(+8.0) 小狂三(-20.0) Zeroの雨(-54.0)
4 | L1002 | 21:30 | 四般南喰赤- | 小狂三(+51.0) Zeroの雨(+15.0) 小宇(-9.0) exia_ang(-57.0)
5 | L1002 | 21:50 | 四般南喰赤- | exia_ang(+41.0) 小狂三(+9.0) 小宇(-20.0) Zeroの雨(-30.0)
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/yaku/types.go:
--------------------------------------------------------------------------------
1 | package yaku
2 |
3 | type HanPoints int
4 | type FuPoints int
5 | type FuPointsRounded int
6 |
7 | func (p FuPoints) Round() FuPointsRounded {
8 | if p == 25 {
9 | return FuPointsRounded(p)
10 | }
11 | left := p % 10
12 | if left == 0 {
13 | return FuPointsRounded(p)
14 | }
15 | return FuPointsRounded(p - left + 10)
16 | }
17 |
--------------------------------------------------------------------------------
/tools/tentool/stats/test_data/sce20180101.html:
--------------------------------------------------------------------------------
1 | 22:27 | 24 | 四琥南喰赤祝2 | 牌譜 | DERESUKE(+64.0,+12枚) siruneko(+10.0,-1枚) リツミサン(-19.0,-3枚) 群青日和@(-55.0,-8枚)
2 | 23:10 | 23 | 四琥南喰赤祝2 | 牌譜 | 群青日和@(+53.0,-2枚) リツミサン(+5.0,-3枚) siruneko(-18.0,+8枚) DERESUKE(-40.0,-3枚)
3 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/pflag/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 |
3 | language: go
4 |
5 | go:
6 | - 1.9.x
7 | - 1.10.x
8 | - 1.11.x
9 | - tip
10 |
11 | matrix:
12 | allow_failures:
13 | - go: tip
14 |
15 | install:
16 | - go get golang.org/x/lint/golint
17 | - export PATH=$GOPATH/bin:$PATH
18 | - go install ./...
19 |
20 | script:
21 | - verify/all.sh -v
22 | - go test ./...
23 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/assert/errors.go:
--------------------------------------------------------------------------------
1 | package assert
2 |
3 | import (
4 | "errors"
5 | )
6 |
7 | // AnError is an error instance useful for testing. If the code does not care
8 | // about error specifics, and only needs to return the error for example, this
9 | // error should be used to make the test code more readable.
10 | var AnError = errors.New("assert.AnError general error for testing")
11 |
--------------------------------------------------------------------------------
/vendor/github.com/c2h5oh/datasize/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
2 | *.o
3 | *.a
4 | *.so
5 |
6 | # Folders
7 | _obj
8 | _test
9 |
10 | # Architecture specific extensions/prefixes
11 | *.[568vq]
12 | [568vq].out
13 |
14 | *.cgo1.go
15 | *.cgo2.c
16 | _cgo_defun.c
17 | _cgo_gotypes.go
18 | _cgo_export.*
19 |
20 | _testmain.go
21 |
22 | *.exe
23 | *.test
24 | *.prof
25 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/genid/name.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package genid
6 |
7 | const (
8 | NoUnkeyedLiteral_goname = "noUnkeyedLiteral"
9 | NoUnkeyedLiteralA_goname = "XXX_NoUnkeyedLiteral"
10 |
11 | BuilderSuffix_goname = "_builder"
12 | )
13 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/runtime/protoiface/legacy.go:
--------------------------------------------------------------------------------
1 | // Copyright 2018 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package protoiface
6 |
7 | type MessageV1 interface {
8 | Reset()
9 | String() string
10 | ProtoMessage()
11 | }
12 |
13 | type ExtensionRangeV1 struct {
14 | Start, End int32 // both inclusive
15 | }
16 |
--------------------------------------------------------------------------------
/tools/tentool/logs/parse.go:
--------------------------------------------------------------------------------
1 | package logs
2 |
3 | import (
4 | "regexp"
5 | "sort"
6 | )
7 |
8 | var reg = regexp.MustCompile(`tenhou\.net/0/\?log=([0-9a-z-]+)`)
9 |
10 | // ParseIDs parses stat file to find ids of logs
11 | func ParseIDs(data string) []string {
12 | sub := reg.FindAllStringSubmatch(data, -1)
13 | res := make([]string, len(sub))
14 | for k, v := range sub {
15 | res[k] = v[1]
16 | }
17 | sort.Strings(res)
18 | return res
19 | }
20 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/editiondefaults/defaults.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package editiondefaults contains the binary representation of the editions
6 | // defaults.
7 | package editiondefaults
8 |
9 | import _ "embed"
10 |
11 | //go:embed editions_defaults.binpb
12 | var Defaults []byte
13 |
--------------------------------------------------------------------------------
/tbase/helpers.go:
--------------------------------------------------------------------------------
1 | package tbase
2 |
3 | import (
4 | "strconv"
5 | "strings"
6 | )
7 |
8 | func IntList(val string) []int {
9 | s := StringList(val)
10 | if s == nil {
11 | return nil
12 | }
13 | x := make([]int, len(s))
14 | for k, v := range s {
15 | i, _ := strconv.Atoi(v)
16 | x[k] = i
17 | }
18 | return x
19 | }
20 |
21 | func StringList(val string) []string {
22 | if val == "" {
23 | return nil
24 | }
25 | return strings.Split(val, ",")
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/genid/doc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package genid contains constants for declarations in descriptor.proto
6 | // and the well-known types.
7 | package genid
8 |
9 | import "google.golang.org/protobuf/reflect/protoreflect"
10 |
11 | const GoogleProtobuf_package protoreflect.FullName = "google.protobuf"
12 |
--------------------------------------------------------------------------------
/vendor/github.com/satori/go.uuid/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 | sudo: false
3 | go:
4 | - 1.2
5 | - 1.3
6 | - 1.4
7 | - 1.5
8 | - 1.6
9 | - 1.7
10 | - 1.8
11 | - 1.9
12 | - tip
13 | matrix:
14 | allow_failures:
15 | - go: tip
16 | fast_finish: true
17 | before_install:
18 | - go get github.com/mattn/goveralls
19 | - go get golang.org/x/tools/cmd/cover
20 | script:
21 | - $HOME/gopath/bin/goveralls -service=travis-ci
22 | notifications:
23 | email: false
24 |
--------------------------------------------------------------------------------
/tools/tentool/Makefile:
--------------------------------------------------------------------------------
1 | tentool_bin := ./gobin/tentool
2 |
3 | gobin:
4 | mkdir gobin
5 |
6 | .PHONY: tentool
7 | tentool:
8 | go build -o $(tentool_bin) "./"
9 |
10 | .PHONY: init
11 | init: tentool
12 | $(tentool_bin) stats init
13 | $(tentool_bin) logs init
14 |
15 | .PHONY: yadisk
16 | yadisk: tentool
17 | $(tentool_bin) stats yadisk
18 | $(tentool_bin) logs yadisk
19 |
20 | .PHONY: download
21 | download: yadisk
22 | $(tentool_bin) stats download
23 | $(tentool_bin) logs update
24 | $(tentool_bin) logs download
25 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/hand/calc/tags.go:
--------------------------------------------------------------------------------
1 | package calc
2 |
3 | type Tags int
4 |
5 | const (
6 | TagChi Tags = 1 << iota
7 | TagPon
8 | TagKan
9 | TagPair
10 | TagTanki
11 | TagKanchan
12 | TagPenchan
13 | TagRyanman
14 | TagComplete
15 | TagKokushi
16 | TagKoksuhi13
17 | TagOpened
18 |
19 | TagHonor
20 | TagTerminal
21 | TagMiddle
22 | )
23 |
24 | func (t Tags) CheckAny(x Tags) bool {
25 | return (t & x) != 0
26 | }
27 |
28 | func (t Tags) CheckAll(x Tags) bool {
29 | return (t & x) == x
30 | }
31 |
--------------------------------------------------------------------------------
/log/xml_test.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | import (
4 | "encoding/xml"
5 | "io/ioutil"
6 | "testing"
7 |
8 | "github.com/stretchr/testify/assert"
9 | "github.com/stretchr/testify/require"
10 |
11 | "github.com/dnovikoff/tenhou/parser"
12 | )
13 |
14 | func TestXML(t *testing.T) {
15 | data, err := ioutil.ReadFile("test_data/example.xml")
16 | require.NoError(t, err)
17 | x := &parser.Root{}
18 | err = xml.Unmarshal(data, &x)
19 | require.NoError(t, err)
20 |
21 | assert.NoError(t, ProcessXMLNodes(x.Nodes, NullController{}))
22 | }
23 |
--------------------------------------------------------------------------------
/tools/tentool/stats/urls.go:
--------------------------------------------------------------------------------
1 | package stats
2 |
3 | const (
4 | MainPageURL = "http://tenhou.net/sc/raw/"
5 | ListURL = "http://tenhou.net/sc/raw/list.cgi"
6 | ListOldURL = "http://tenhou.net/sc/raw/list.cgi?old"
7 | )
8 |
9 | func MakeFullURL(short string) string {
10 | return MainPageURL + short
11 | }
12 |
13 | func MakeFullURLs(short []string) []string {
14 | if short == nil {
15 | return nil
16 | }
17 | x := make([]string, len(short))
18 | for k, v := range short {
19 | x[k] = MakeFullURL(v)
20 | }
21 | return x
22 | }
23 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/genid/wrappers.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package genid
6 |
7 | import "google.golang.org/protobuf/reflect/protoreflect"
8 |
9 | // Generic field name and number for messages in wrappers.proto.
10 | const (
11 | WrapperValue_Value_field_name protoreflect.Name = "value"
12 | WrapperValue_Value_field_number protoreflect.FieldNumber = 1
13 | )
14 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/assert/forward_assertions.go:
--------------------------------------------------------------------------------
1 | package assert
2 |
3 | // Assertions provides assertion methods around the
4 | // TestingT interface.
5 | type Assertions struct {
6 | t TestingT
7 | }
8 |
9 | // New makes a new Assertions object for the specified TestingT.
10 | func New(t TestingT) *Assertions {
11 | return &Assertions{
12 | t: t,
13 | }
14 | }
15 |
16 | //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_forward.go.tmpl -include-format-funcs"
17 |
--------------------------------------------------------------------------------
/tools/tentool/logs/cmd_status.go:
--------------------------------------------------------------------------------
1 | package logs
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/dnovikoff/tenhou/tools/tentool/utils"
7 | )
8 |
9 | func Status() {
10 | index, err := LoadIndex()
11 | utils.Check(err)
12 | total := index.Len()
13 | if total == 0 {
14 | fmt.Println("No logs downloaded")
15 | return
16 | }
17 | downloaded := 0
18 | for _, v := range index.indexed {
19 | if v.Check() {
20 | downloaded++
21 | }
22 | }
23 | fmt.Printf("Downloaded %v ot of %v files (%v%%)\n", downloaded, total, downloaded*100/total)
24 | }
25 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/require/forward_requirements.go:
--------------------------------------------------------------------------------
1 | package require
2 |
3 | // Assertions provides assertion methods around the
4 | // TestingT interface.
5 | type Assertions struct {
6 | t TestingT
7 | }
8 |
9 | // New makes a new Assertions object for the specified TestingT.
10 | func New(t TestingT) *Assertions {
11 | return &Assertions{
12 | t: t,
13 | }
14 | }
15 |
16 | //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require_forward.go.tmpl -include-format-funcs"
17 |
--------------------------------------------------------------------------------
/parser/parse.go:
--------------------------------------------------------------------------------
1 | package parser
2 |
3 | import (
4 | "encoding/xml"
5 | "strings"
6 |
7 | "github.com/facebookgo/stackerr"
8 | )
9 |
10 | func ParseXML(input string) (ret Nodes, err error) {
11 | // Dirty hack
12 | input = "" + input + ""
13 | d := xml.NewDecoder(strings.NewReader(input))
14 | d.Strict = false
15 | var root Root
16 | err = stackerr.Wrap(d.Decode(&root))
17 | for k, v := range root.Nodes {
18 | if len(v.Attributes) == 0 {
19 | root.Nodes[k].Attributes = nil
20 | }
21 | }
22 | ret = root.Nodes
23 | return
24 | }
25 |
--------------------------------------------------------------------------------
/server/xml_test.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | "github.com/stretchr/testify/require"
8 | )
9 |
10 | func TestJoinWrite(t *testing.T) {
11 | c := NewXMLWriter()
12 | c.CancelJoin()
13 | c.Join(0, 9, false)
14 | c.Join(1, 2, true)
15 |
16 | assert.Equal(t, ` `, c.String())
17 | c2 := NewXMLWriter()
18 | require.NoError(t, ProcessXMLMessage(c.String(), c2))
19 | assert.Equal(t, ` `, c2.String())
20 | }
21 |
--------------------------------------------------------------------------------
/tbase/sex.go:
--------------------------------------------------------------------------------
1 | package tbase
2 |
3 | type Sex int
4 |
5 | const (
6 | SexUnknown Sex = iota
7 | SexMale
8 | SexFemale
9 | SexComputer
10 | )
11 |
12 | func (sx Sex) Letter() string {
13 | switch sx {
14 | case SexMale:
15 | return "M"
16 | case SexFemale:
17 | return "F"
18 | case SexComputer:
19 | return "C"
20 | }
21 | return "?"
22 | }
23 |
24 | func ParseSexLetter(in string) Sex {
25 | switch in {
26 | case "M":
27 | return SexMale
28 | case "F":
29 | return SexFemale
30 | case "C":
31 | return SexComputer
32 | }
33 | return SexUnknown
34 | }
35 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/impl/codec_unsafe.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package impl
6 |
7 | // When using unsafe pointers, we can just treat enum values as int32s.
8 |
9 | var (
10 | coderEnumNoZero = coderInt32NoZero
11 | coderEnum = coderInt32
12 | coderEnumPtr = coderInt32Ptr
13 | coderEnumSlice = coderInt32Slice
14 | coderEnumPackedSlice = coderInt32PackedSlice
15 | )
16 |
--------------------------------------------------------------------------------
/tools/tentool/logs/cmd_collect.go:
--------------------------------------------------------------------------------
1 | package logs
2 |
3 | import (
4 | "fmt"
5 | "io/ioutil"
6 |
7 | "github.com/dnovikoff/tenhou/tools/tentool/utils"
8 | )
9 |
10 | func Collect(args []string) {
11 | index, err := LoadIndex()
12 | utils.Check(err)
13 | newLinks := 0
14 | for _, v := range args {
15 | bytes, err := ioutil.ReadFile(v)
16 | utils.Check(err)
17 | links := ParseIDs(string(bytes))
18 | newLinks += index.AddIDs(links)
19 | }
20 | fmt.Printf("Found %v new links provided files. New database size: %v\n", newLinks, index.Len())
21 | utils.Check(index.Save())
22 | }
23 |
--------------------------------------------------------------------------------
/vendor/github.com/facebookgo/stackerr/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | go:
4 | - 1.2
5 | - 1.3
6 |
7 | matrix:
8 | fast_finish: true
9 |
10 | before_install:
11 | - go get -v code.google.com/p/go.tools/cmd/vet
12 | - go get -v github.com/golang/lint/golint
13 | - go get -v code.google.com/p/go.tools/cmd/cover
14 |
15 | install:
16 | - go install -race -v std
17 | - go get -race -t -v ./...
18 | - go install -race -v ./...
19 |
20 | script:
21 | - go vet ./...
22 | - $HOME/gopath/bin/golint .
23 | - go test -cpu=2 -race -v ./...
24 | - go test -cpu=2 -covermode=atomic ./...
25 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/hand/calc/meld_debug.go:
--------------------------------------------------------------------------------
1 | package calc
2 |
3 | import (
4 | "strings"
5 | )
6 |
7 | func DebugMeld(m Meld) string {
8 | if m == nil {
9 | return "nil"
10 | }
11 | x := m.Tiles().String()
12 | w := m.Waits()
13 | if len(w) > 0 {
14 | x += " (" + w.String() + ")"
15 | }
16 | return x
17 | }
18 |
19 | func DebugMeldsString(m Melds) string {
20 | return strings.Join(DebugMelds(m), " ")
21 | }
22 |
23 | func DebugMelds(m Melds) []string {
24 | data := make([]string, len(m))
25 | for k, v := range m {
26 | data[k] = DebugMeld(v)
27 | }
28 | return data
29 | }
30 |
--------------------------------------------------------------------------------
/vendor/github.com/inconshreveable/mousetrap/trap_others.go:
--------------------------------------------------------------------------------
1 | //go:build !windows
2 | // +build !windows
3 |
4 | package mousetrap
5 |
6 | // StartedByExplorer returns true if the program was invoked by the user
7 | // double-clicking on the executable from explorer.exe
8 | //
9 | // It is conservative and returns false if any of the internal calls fail.
10 | // It does not guarantee that the program was run from a terminal. It only can tell you
11 | // whether it was launched from explorer.exe
12 | //
13 | // On non-Windows platforms, it always returns false.
14 | func StartedByExplorer() bool {
15 | return false
16 | }
17 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/protolazy/pointer_unsafe.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package protolazy
6 |
7 | import (
8 | "sync/atomic"
9 | "unsafe"
10 | )
11 |
12 | func atomicLoadIndex(p **[]IndexEntry) *[]IndexEntry {
13 | return (*[]IndexEntry)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
14 | }
15 | func atomicStoreIndex(p **[]IndexEntry, v *[]IndexEntry) {
16 | atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
17 | }
18 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/yaku/fu.go:
--------------------------------------------------------------------------------
1 | package yaku
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/hand/calc"
5 | )
6 |
7 | func GetMeldFu(m calc.Meld) FuPoints {
8 | tags := m.Tags()
9 | if tags.CheckAny(calc.TagKanchan | calc.TagPenchan | calc.TagTanki) {
10 | return 2
11 | }
12 | if !tags.CheckAny(calc.TagPon) {
13 | return 0
14 | }
15 | var value FuPoints = 2
16 | if tags.CheckAny(calc.TagTerminal | calc.TagHonor) {
17 | value = 4
18 | }
19 | if !tags.CheckAny(calc.TagOpened) {
20 | value *= 2
21 | }
22 | if tags.CheckAny(calc.TagKan) {
23 | value *= 4
24 | }
25 | return value
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/NOTICE:
--------------------------------------------------------------------------------
1 | Copyright 2011-2016 Canonical Ltd.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v3/NOTICE:
--------------------------------------------------------------------------------
1 | Copyright 2011-2016 Canonical Ltd.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/tbase/draw.go:
--------------------------------------------------------------------------------
1 | package tbase
2 |
3 | type DrawType int
4 |
5 | const (
6 | DrawUnknown DrawType = iota
7 | DrawEnd
8 | Draw9
9 | DrawReach4
10 | DrawRon3
11 | DrawKan4
12 | DrawWind4
13 | DrawNagashi
14 | )
15 |
16 | var DrawMap = map[string]DrawType{
17 | "": DrawEnd,
18 | "yao9": Draw9,
19 | "reach4": DrawReach4,
20 | "ron3": DrawRon3,
21 | "kan4": DrawKan4,
22 | "kaze4": DrawWind4,
23 | "nm": DrawNagashi,
24 | }
25 |
26 | var ReverseDrawMap = func() map[DrawType]string {
27 | ret := make(map[DrawType]string, len(DrawMap))
28 | for k, v := range DrawMap {
29 | ret[v] = k
30 | }
31 | return ret
32 | }()
33 |
--------------------------------------------------------------------------------
/tools/tentool/stats/test_data/scf.log:
--------------------------------------------------------------------------------
1 | C0431 | 20:08 | 四般南喰赤- | 牌譜 | Ⓟ豊後葵(+56.0) 【罪歌】(+10.0) Ⓟ小川裕之(-20.0) みかん太(-46.0)
2 | C0431 | 20:48 | 四般南喰赤- | 牌譜 | みかん太(+53.0) Ⓟ小川裕之(+11.0) 【罪歌】(-11.0) Ⓟ豊後葵(-53.0)
3 | C0431 | 21:17 | 四般南喰赤- | 牌譜 | Ⓟ豊後葵(+54.0) みかん太(+17.0) Ⓟ小川裕之(-21.0) 【罪歌】(-50.0)
4 | C0431 | 21:47 | 四般南喰赤- | 牌譜 | Ⓟ豊後葵(+54.0) 【罪歌】(+17.0) Ⓟ小川裕之(-29.0) みかん太(-42.0)
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/proto/proto_reflect.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // The protoreflect build tag disables use of fast-path methods.
6 | //go:build protoreflect
7 | // +build protoreflect
8 |
9 | package proto
10 |
11 | import (
12 | "google.golang.org/protobuf/reflect/protoreflect"
13 | "google.golang.org/protobuf/runtime/protoiface"
14 | )
15 |
16 | const hasProtoMethods = false
17 |
18 | func protoMethods(m protoreflect.Message) *protoiface.Methods {
19 | return nil
20 | }
21 |
--------------------------------------------------------------------------------
/tools/tentool/utils/routines.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "sync"
5 | "sync/atomic"
6 | )
7 |
8 | type Routines struct {
9 | wg sync.WaitGroup
10 | lastError atomic.Value
11 | }
12 |
13 | func (r *Routines) Start(f func() error) {
14 | r.wg.Add(1)
15 | go func() {
16 | defer r.wg.Done()
17 | err := f()
18 | if err != nil {
19 | r.lastError.Store(err)
20 | }
21 | }()
22 | }
23 |
24 | func (r *Routines) Error() error {
25 | x := r.lastError.Load()
26 | if x == nil {
27 | return nil
28 | }
29 | return x.(error)
30 | }
31 |
32 | func (r *Routines) Wait() error {
33 | r.wg.Wait()
34 | return r.Error()
35 | }
36 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/genid/map_entry.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package genid
6 |
7 | import "google.golang.org/protobuf/reflect/protoreflect"
8 |
9 | // Generic field names and numbers for synthetic map entry messages.
10 | const (
11 | MapEntry_Key_field_name protoreflect.Name = "key"
12 | MapEntry_Value_field_name protoreflect.Name = "value"
13 |
14 | MapEntry_Key_field_number protoreflect.FieldNumber = 1
15 | MapEntry_Value_field_number protoreflect.FieldNumber = 2
16 | )
17 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/proto/proto_methods.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // The protoreflect build tag disables use of fast-path methods.
6 | //go:build !protoreflect
7 | // +build !protoreflect
8 |
9 | package proto
10 |
11 | import (
12 | "google.golang.org/protobuf/reflect/protoreflect"
13 | "google.golang.org/protobuf/runtime/protoiface"
14 | )
15 |
16 | const hasProtoMethods = true
17 |
18 | func protoMethods(m protoreflect.Message) *protoiface.Methods {
19 | return m.ProtoMethods()
20 | }
21 |
--------------------------------------------------------------------------------
/network/auth_test.go:
--------------------------------------------------------------------------------
1 | package network
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | )
8 |
9 | func TestAuth(t *testing.T) {
10 | tst := func(in string) string {
11 | ret, err := AuthAnswer(in)
12 | if err != nil {
13 | return err.Error()
14 | }
15 | return ret
16 | }
17 | assert.Equal(t, "20180117-c1ebb26f", tst("20180117-e7b5e83e"))
18 | assert.Equal(t, "Wrong size", tst("2018011-e7b5e83e"))
19 | assert.Equal(t, "Wrong size", tst("20180117-e7b5e83"))
20 | assert.Equal(t, "Wrong parts", tst("20180117e7b5e83e"))
21 | assert.Equal(t, "strconv.ParseInt: parsing \"2180a17\": invalid syntax", tst("2a180a17-e7b5e83e"))
22 | }
23 |
--------------------------------------------------------------------------------
/vendor/github.com/facebookgo/stack/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 |
3 | go:
4 | - 1.3
5 |
6 | matrix:
7 | fast_finish: true
8 |
9 | before_install:
10 | - if ! go get code.google.com/p/go.tools/cmd/vet; then go get golang.org/x/tools/cmd/vet; fi
11 | - go get -v github.com/golang/lint/golint
12 | - if ! go get code.google.com/p/go.tools/cmd/cover; then go get golang.org/x/tools/cmd/cover; fi
13 |
14 | install:
15 | - go install -race -v std
16 | - go get -race -t -v ./...
17 | - go install -race -v ./...
18 |
19 | script:
20 | - go vet ./...
21 | - $HOME/gopath/bin/golint .
22 | - go test -cpu=2 -race -v ./...
23 | - go test -cpu=2 -covermode=atomic ./...
24 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/genid/empty_gen.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Code generated by generate-protos. DO NOT EDIT.
6 |
7 | package genid
8 |
9 | import (
10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect"
11 | )
12 |
13 | const File_google_protobuf_empty_proto = "google/protobuf/empty.proto"
14 |
15 | // Names for google.protobuf.Empty.
16 | const (
17 | Empty_message_name protoreflect.Name = "Empty"
18 | Empty_message_fullname protoreflect.FullName = "google.protobuf.Empty"
19 | )
20 |
--------------------------------------------------------------------------------
/tools/tentool/logs/cmd_yadisk.go:
--------------------------------------------------------------------------------
1 | package logs
2 |
3 | import (
4 | "github.com/dnovikoff/tenhou/tools/tentool/utils"
5 | )
6 |
7 | type yadisk struct {
8 | interactive bool
9 | index *FileIndex
10 | }
11 |
12 | func (y *yadisk) Run(args []string) {
13 | index, err := LoadIndex()
14 | utils.Check(err)
15 | y.index = index
16 | if len(args) == 0 {
17 | args = []string{"https://yadi.sk/d/FIIkaucSNjR3Kw"}
18 | }
19 | for _, v := range args {
20 | utils.Check(y.download(v))
21 | }
22 | }
23 |
24 | func (y *yadisk) download(u string) error {
25 | return utils.YaDiskDownload(u, Location, y.interactive, func(_, p string) error {
26 | return addZipToIndex(y.index, p)
27 | })
28 | }
29 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/base/wind.go:
--------------------------------------------------------------------------------
1 | package base
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/tile"
5 | )
6 |
7 | //go:generate stringer -type=Wind
8 | type Wind int
9 |
10 | const (
11 | WindEast Wind = iota
12 | WindSouth
13 | WindWest
14 | WindNorth
15 | WindEnd
16 | )
17 |
18 | func (w Wind) tile() tile.Tile {
19 | return tile.Tile(w) + tile.East
20 | }
21 |
22 | func (w Wind) CheckTile(t tile.Tile) bool {
23 | return w.tile() == t
24 | }
25 |
26 | func (w Wind) fix() Wind {
27 | if w < 0 {
28 | return (w + (4 * (w / -4)) + 4) % 4
29 | }
30 | return w % 4
31 | }
32 |
33 | func (w Wind) Advance(num int) Wind {
34 | return (w + Wind(num)).fix()
35 | }
36 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/cobra/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files, Static and Dynamic libs (Shared Objects)
2 | *.o
3 | *.a
4 | *.so
5 |
6 | # Folders
7 | _obj
8 | _test
9 |
10 | # Architecture specific extensions/prefixes
11 | *.[568vq]
12 | [568vq].out
13 |
14 | *.cgo1.go
15 | *.cgo2.c
16 | _cgo_defun.c
17 | _cgo_gotypes.go
18 | _cgo_export.*
19 |
20 | _testmain.go
21 |
22 | # Vim files https://github.com/github/gitignore/blob/master/Global/Vim.gitignore
23 | # swap
24 | [._]*.s[a-w][a-z]
25 | [._]s[a-w][a-z]
26 | # session
27 | Session.vim
28 | # temporary
29 | .netrwhist
30 | *~
31 | # auto-generated tag files
32 | tags
33 |
34 | *.exe
35 | cobra.test
36 | bin
37 |
38 | .idea/
39 | *.iml
40 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/tile/type.go:
--------------------------------------------------------------------------------
1 | package tile
2 |
3 | type Type int
4 |
5 | const (
6 | TypeMan Type = Type(Man1)
7 | TypePin Type = Type(Pin1)
8 | TypeSou Type = Type(Sou1)
9 | TypeWind Type = Type(East)
10 | TypeDragon Type = Type(White)
11 | TypeNull Type = Type(TileNull)
12 | )
13 |
14 | func (t Type) Tile(num int) Tile {
15 | return Tile(t) + Tile(num-1)
16 | }
17 |
18 | // TypeRune used for stringifying tiles
19 | func TypeRune(t Type) rune {
20 | switch t {
21 | case TypeMan:
22 | return 'm'
23 | case TypePin:
24 | return 'p'
25 | case TypeSou:
26 | return 's'
27 | case TypeDragon, TypeWind:
28 | return 'z'
29 | }
30 | return '-'
31 | }
32 |
--------------------------------------------------------------------------------
/tools/tentool/stats/cmd_yadisk.go:
--------------------------------------------------------------------------------
1 | package stats
2 |
3 | import (
4 | "github.com/dnovikoff/tenhou/tools/tentool/utils"
5 | )
6 |
7 | type yadisk struct {
8 | interactive bool
9 | index *FileIndex
10 | }
11 |
12 | func (y *yadisk) Run(args []string) {
13 | index, err := LoadIndex()
14 | utils.Check(err)
15 | y.index = index
16 | if len(args) == 0 {
17 | args = []string{"https://yadi.sk/d/uOv87aVsd-l-3A"}
18 | }
19 | for _, v := range args {
20 | utils.Check(y.download(v))
21 | }
22 | }
23 |
24 | func (y *yadisk) download(u string) error {
25 | return utils.YaDiskDownload(u, Location, y.interactive, func(publicURL, path string) error {
26 | return y.index.Add(publicURL, path)
27 | })
28 | }
29 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/genid/goname.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package genid
6 |
7 | // Go names of implementation-specific struct fields in generated messages.
8 | const (
9 | State_goname = "state"
10 |
11 | SizeCache_goname = "sizeCache"
12 | SizeCacheA_goname = "XXX_sizecache"
13 |
14 | UnknownFields_goname = "unknownFields"
15 | UnknownFieldsA_goname = "XXX_unrecognized"
16 |
17 | ExtensionFields_goname = "extensionFields"
18 | ExtensionFieldsA_goname = "XXX_InternalExtensions"
19 | ExtensionFieldsB_goname = "XXX_extensions"
20 | )
21 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/impl/enum.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package impl
6 |
7 | import (
8 | "reflect"
9 |
10 | "google.golang.org/protobuf/reflect/protoreflect"
11 | )
12 |
13 | type EnumInfo struct {
14 | GoReflectType reflect.Type // int32 kind
15 | Desc protoreflect.EnumDescriptor
16 | }
17 |
18 | func (t *EnumInfo) New(n protoreflect.EnumNumber) protoreflect.Enum {
19 | return reflect.ValueOf(n).Convert(t.GoReflectType).Interface().(protoreflect.Enum)
20 | }
21 | func (t *EnumInfo) Descriptor() protoreflect.EnumDescriptor { return t.Desc }
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: generate
2 | all: generate test build
3 |
4 | include protoc.mk
5 |
6 | gobin:
7 | mkdir gobin
8 |
9 | # github.com/golang/protobuf/protoc-gen-go
10 | CMD := $(protoc_go_cmd) --go_out=paths=source_relative,plugins=grpc:./genproto --proto_path=./proto
11 |
12 | .PHONY: generate
13 | generate: $(protoc_gen_go)
14 | rm -rf genproto
15 | mkdir genproto
16 | # cd proto &&
17 | $(CMD) ./proto/stats/*.proto
18 |
19 | .PHONY: test
20 | test:
21 | go test -mod vendor ./...
22 |
23 | .PHONY: build
24 | build:
25 | mkdir -p build
26 | GOBIN=$(shell pwd)/build go install -mod vendor ./cmd/...
27 |
28 | .PHONY: testcover
29 | testcover:
30 | go test -mod vendor -race -coverprofile=coverage.txt -covermode=atomic ./...
31 |
--------------------------------------------------------------------------------
/tbase/yaku_test.go:
--------------------------------------------------------------------------------
1 | package tbase
2 |
3 | // func TestYakuParse(t *testing.T) {
4 | // ret, err := ParseYakuList("35,6,52,2,54,1")
5 | // require.NoError(t, err)
6 | // assert.Equal(t, "YakuAkaDora: 1, YakuChinitsu: 6, YakuDora: 2", ret.String())
7 | // }
8 |
9 | // func TestYakuParseWrong(t *testing.T) {
10 | // _, err := ParseYakuList("35,6,52,2,a54,1")
11 | // require.Error(t, err)
12 | // assert.Contains(t, err.Error(), "invalid syntax")
13 | // _, err = ParseYakuList("35,6,52,2,54,")
14 | // require.Error(t, err)
15 | // assert.Contains(t, err.Error(), "invalid syntax")
16 | // _, err = ParseYakuList("35,6,52,2,154,1")
17 | // require.Error(t, err)
18 | // assert.Contains(t, err.Error(), "Yaku with value 154 not found in map")
19 | // }
20 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/hand/calc/meld_stack.go:
--------------------------------------------------------------------------------
1 | package calc
2 |
3 | type meldStack struct {
4 | melds Melds
5 | index int
6 | }
7 |
8 | func newMeldStack(capacity int) *meldStack {
9 | return &meldStack{
10 | melds: make(Melds, capacity),
11 | }
12 | }
13 |
14 | func (ms *meldStack) size() int {
15 | return ms.index
16 | }
17 |
18 | func (ms *meldStack) reset() {
19 | ms.index = 0
20 | }
21 |
22 | func (ms *meldStack) push(meld Meld) {
23 | ms.melds[ms.index] = meld
24 | ms.index++
25 | }
26 |
27 | func (ms *meldStack) getMelds() Melds {
28 | return ms.melds[:ms.index]
29 | }
30 |
31 | func (ms *meldStack) back() Meld {
32 | return ms.melds[ms.index-1]
33 | }
34 |
35 | func (ms *meldStack) pop() {
36 | ms.index--
37 | }
38 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go:
--------------------------------------------------------------------------------
1 | //go:build testify_yaml_fail && !testify_yaml_custom && !testify_yaml_default
2 | // +build testify_yaml_fail,!testify_yaml_custom,!testify_yaml_default
3 |
4 | // Package yaml is an implementation of YAML functions that always fail.
5 | //
6 | // This implementation can be used at build time to replace the default implementation
7 | // to avoid linking with [gopkg.in/yaml.v3]:
8 | //
9 | // go test -tags testify_yaml_fail
10 | package yaml
11 |
12 | import "errors"
13 |
14 | var errNotImplemented = errors.New("YAML functions are not available (see https://pkg.go.dev/github.com/stretchr/testify/assert/yaml)")
15 |
16 | func Unmarshal([]byte, interface{}) error {
17 | return errNotImplemented
18 | }
19 |
--------------------------------------------------------------------------------
/network/examples/doc.txt:
--------------------------------------------------------------------------------
1 | 1. Все сообщения от сервера и от клиента заканчиваются на терминальный ноль "\0" или "\x00". Сервер может присылать за раз несколько сообщений. Но это не критично и бот умеет работать с одним сообщением за раз.
2 | 2. Есть два основных типа сообщений. Сообщения лично для клиента, которые требуют его действий (например открытия) и общие сообщения про происходящее на столе.
3 | 3. Взятие клиента кодируется как (присылает сервер), сброс клиента
4 | 4. Сброс другого игрока . e - шимоча, f - тоймен, g - камича. После сброса игрока отсылается еще один тег, который обозначает конец хода игрока. Например полный сброс тоймена будет выглядеть как " ". Маленькая буква обозначает цумогири, большая буква обозначает сброс из руки.
5 |
--------------------------------------------------------------------------------
/tools/tentool/logs/id_test.go:
--------------------------------------------------------------------------------
1 | package logs
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | "github.com/stretchr/testify/require"
8 | )
9 |
10 | func TestParseLogID(t *testing.T) {
11 | fullID := "2018092823gm-00a9-0000-2735720b"
12 | parsed := ParseID(fullID)
13 | assert.Equal(t, &ParsedID{
14 | Time: "2018092823gm",
15 | Type: "00a9",
16 | Number: "0000",
17 | OriginalID: "2735720b",
18 | DownloadID: "2735720b"},
19 | parsed)
20 | assert.Equal(t, "https://tenhou.net/0/log/?2018092823gm-00a9-0000-2735720b", GetDownloadLink(parsed))
21 | path, err := GetFilePath(parsed, fullID)
22 | require.NoError(t, err)
23 | assert.Equal(t, "0000/00a9/2018/09/28/23/2018092823gm-00a9-0000-2735720b", path)
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/compact/packed_masks.go:
--------------------------------------------------------------------------------
1 | package compact
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/tile"
5 | )
6 |
7 | type PackedMasks uint64
8 |
9 | func SinglePackedMasks(mask Mask, index uint) PackedMasks {
10 | return PackedMasks(mask.Mask() << (4 * index))
11 | }
12 |
13 | func (pm PackedMasks) Set(mask Mask, index uint) PackedMasks {
14 | erase := ^SinglePackedMasks(15, index)
15 | return (pm & erase) | SinglePackedMasks(mask, index)
16 | }
17 |
18 | func (pm PackedMasks) Get(index uint, tile tile.Tile) Mask {
19 | return NewMask(uint(pm)>>(4*index), tile)
20 | }
21 |
22 | func (pm PackedMasks) CountBits() int {
23 | cnt := 0
24 |
25 | for pm > 0 {
26 | cnt += int(pm & 1)
27 | pm >>= 1
28 | }
29 | return cnt
30 | }
31 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/hand/tempai/debug.go:
--------------------------------------------------------------------------------
1 | package tempai
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 | "strings"
7 |
8 | "github.com/dnovikoff/tempai-core/hand/calc"
9 | )
10 |
11 | func DebugTempai(in *TempaiResult) string {
12 | buf := &bytes.Buffer{}
13 | // fmt.Fprintf(buf, "%v", in.Type)
14 | // fmt.Fprintf(buf, " Tiles: %v", in.Closed.Instances())
15 | // if in.Declared != nil {
16 | // fmt.Fprintf(buf, " [%v]", meld.DebugMelds(in.Declared))
17 | // }
18 | if in.Pair != nil {
19 | fmt.Fprintf(buf, " %v", calc.DebugMeld(in.Pair))
20 | }
21 | if in.Melds != nil {
22 | fmt.Fprintf(buf, " %v", calc.DebugMeldsString(in.Melds))
23 | }
24 | fmt.Fprintf(buf, " %v", calc.DebugMeld(in.Last))
25 | return strings.TrimSpace(buf.String())
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/yaku/limit.go:
--------------------------------------------------------------------------------
1 | package yaku
2 |
3 | type Limit int
4 |
5 | //go:generate stringer -type=Limit
6 | // Limit numbers are now fixed and should not be changed
7 | const (
8 | LimitNone Limit = 0
9 | LimitMangan Limit = 1
10 | LimitHaneman Limit = 2
11 | LimitBaiman Limit = 3
12 | LimitSanbaiman Limit = 4
13 | LimitYakuman Limit = 5
14 | )
15 |
16 | func (lim Limit) ShortString() string {
17 | return lim.String()[len("Limit"):]
18 | }
19 |
20 | func (lim Limit) BaseHans() HanPoints {
21 | switch lim {
22 | case LimitMangan:
23 | return 5
24 | case LimitHaneman:
25 | return 6
26 | case LimitBaiman:
27 | return 8
28 | case LimitSanbaiman:
29 | return 11
30 | case LimitYakuman:
31 | return 13
32 | }
33 | return 0
34 | }
35 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/editionssupport/editions.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package editionssupport defines constants for editions that are supported.
6 | package editionssupport
7 |
8 | import "google.golang.org/protobuf/types/descriptorpb"
9 |
10 | const (
11 | Minimum = descriptorpb.Edition_EDITION_PROTO2
12 | Maximum = descriptorpb.Edition_EDITION_2023
13 |
14 | // MaximumKnown is the maximum edition that is known to Go Protobuf, but not
15 | // declared as supported. In other words: end users cannot use it, but
16 | // testprotos inside Go Protobuf can.
17 | MaximumKnown = descriptorpb.Edition_EDITION_2024
18 | )
19 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/writerc.go:
--------------------------------------------------------------------------------
1 | package yaml
2 |
3 | // Set the writer error and return false.
4 | func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool {
5 | emitter.error = yaml_WRITER_ERROR
6 | emitter.problem = problem
7 | return false
8 | }
9 |
10 | // Flush the output buffer.
11 | func yaml_emitter_flush(emitter *yaml_emitter_t) bool {
12 | if emitter.write_handler == nil {
13 | panic("write handler not set")
14 | }
15 |
16 | // Check if the buffer is empty.
17 | if emitter.buffer_pos == 0 {
18 | return true
19 | }
20 |
21 | if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
22 | return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
23 | }
24 | emitter.buffer_pos = 0
25 | return true
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/cobra/command_notwin.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013-2023 The Cobra Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | //go:build !windows
16 | // +build !windows
17 |
18 | package cobra
19 |
20 | var preExecHookFn func(*Command)
21 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/hand/tempai/type_string.go:
--------------------------------------------------------------------------------
1 | // Code generated by "stringer -type=Type"; DO NOT EDIT.
2 |
3 | package tempai
4 |
5 | import "strconv"
6 |
7 | func _() {
8 | // An "invalid array index" compiler error signifies that the constant values have changed.
9 | // Re-run the stringer command to generate them again.
10 | var x [1]struct{}
11 | _ = x[TypeNone-0]
12 | _ = x[TypeRegular-1]
13 | _ = x[TypePairs-2]
14 | _ = x[TypeKokushi-3]
15 | }
16 |
17 | const _Type_name = "TypeNoneTypeRegularTypePairsTypeKokushi"
18 |
19 | var _Type_index = [...]uint8{0, 8, 19, 28, 39}
20 |
21 | func (i Type) String() string {
22 | if i < 0 || i >= Type(len(_Type_index)-1) {
23 | return "Type(" + strconv.FormatInt(int64(i), 10) + ")"
24 | }
25 | return _Type_name[_Type_index[i]:_Type_index[i+1]]
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/base/wind_string.go:
--------------------------------------------------------------------------------
1 | // Code generated by "stringer -type=Wind"; DO NOT EDIT.
2 |
3 | package base
4 |
5 | import "strconv"
6 |
7 | func _() {
8 | // An "invalid array index" compiler error signifies that the constant values have changed.
9 | // Re-run the stringer command to generate them again.
10 | var x [1]struct{}
11 | _ = x[WindEast-0]
12 | _ = x[WindSouth-1]
13 | _ = x[WindWest-2]
14 | _ = x[WindNorth-3]
15 | _ = x[WindEnd-4]
16 | }
17 |
18 | const _Wind_name = "WindEastWindSouthWindWestWindNorthWindEnd"
19 |
20 | var _Wind_index = [...]uint8{0, 8, 17, 25, 34, 41}
21 |
22 | func (i Wind) String() string {
23 | if i < 0 || i >= Wind(len(_Wind_index)-1) {
24 | return "Wind(" + strconv.FormatInt(int64(i), 10) + ")"
25 | }
26 | return _Wind_name[_Wind_index[i]:_Wind_index[i+1]]
27 | }
28 |
--------------------------------------------------------------------------------
/vendor/github.com/davecgh/go-spew/LICENSE:
--------------------------------------------------------------------------------
1 | ISC License
2 |
3 | Copyright (c) 2012-2016 Dave Collins
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted, provided that the above
7 | copyright notice and this permission notice appear in all copies.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 |
--------------------------------------------------------------------------------
/vendor/go.uber.org/multierr/.codecov.yml:
--------------------------------------------------------------------------------
1 | coverage:
2 | range: 80..100
3 | round: down
4 | precision: 2
5 |
6 | status:
7 | project: # measuring the overall project coverage
8 | default: # context, you can create multiple ones with custom titles
9 | enabled: yes # must be yes|true to enable this status
10 | target: 100 # specify the target coverage for each commit status
11 | # option: "auto" (must increase from parent commit or pull request base)
12 | # option: "X%" a static target percentage to hit
13 | if_not_found: success # if parent is not found report status as success, error, or failure
14 | if_ci_failed: error # if ci fails report status as success, error, or failure
15 |
16 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/yaku/resources.go:
--------------------------------------------------------------------------------
1 | package yaku
2 |
3 | type Dictionary map[string]string
4 |
5 | func AppendResources8(in Dictionary, str string, indexes []uint8) Dictionary {
6 | for i := 0; i < len(indexes)-1; i++ {
7 | in[str[indexes[i]:indexes[i+1]]] = ""
8 | }
9 | return in
10 | }
11 |
12 | func AppendResources16(in Dictionary, str string, indexes []uint16) Dictionary {
13 | for i := 0; i < len(indexes)-1; i++ {
14 | in[str[indexes[i]:indexes[i+1]]] = ""
15 | }
16 | return in
17 | }
18 |
19 | func GetResources() Dictionary {
20 | mp := make(Dictionary)
21 | mp = AppendResources16(mp, _Yaku_name, _Yaku_index[:])
22 | mp = AppendResources16(mp, _Yakuman_name, _Yakuman_index[:])
23 | mp = AppendResources8(mp, _Fu_name, _Fu_index[:])
24 | mp = AppendResources8(mp, _Limit_name, _Limit_index[:])
25 | return mp
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/compact/test_generator.go:
--------------------------------------------------------------------------------
1 | package compact
2 |
3 | import (
4 | "github.com/stretchr/testify/require"
5 |
6 | "github.com/dnovikoff/tempai-core/tile"
7 | )
8 |
9 | type TestGenerator struct {
10 | impl *Generator
11 | t require.TestingT
12 | }
13 |
14 | func NewTestGenerator(t require.TestingT) *TestGenerator {
15 | return &TestGenerator{NewTileGenerator(), t}
16 | }
17 |
18 | func (tg *TestGenerator) TilesLeft() tile.Instances {
19 | return tg.impl.TilesLeft()
20 | }
21 |
22 | func (tg *TestGenerator) InstancesFromString(str string) tile.Instances {
23 | x, err := tg.impl.InstancesFromString(str)
24 | require.NoError(tg.t, err)
25 | return x
26 | }
27 |
28 | func (tg *TestGenerator) CompactFromString(str string) Instances {
29 | x, err := tg.impl.CompactFromString(str)
30 | require.NoError(tg.t, err)
31 | return x
32 | }
33 |
--------------------------------------------------------------------------------
/server/examples_test.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "strings"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/require"
8 |
9 | "github.com/dnovikoff/tenhou/tbase"
10 | "github.com/dnovikoff/tenhou/util"
11 | )
12 |
13 | type exampleWriter struct {
14 | XMLWriter
15 | t *testing.T
16 | }
17 |
18 | const goodID = "IDDEADBEAF-xxxxxxxx"
19 |
20 | func (w exampleWriter) Hello(name string, tid string, sex tbase.Sex) {
21 | if name != goodID {
22 | require.False(w.t, strings.HasPrefix(name, "ID"), "remove sensetive data "+name)
23 | }
24 | w.XMLWriter.Hello(name, tid, sex)
25 | }
26 |
27 | func TestExamples(t *testing.T) {
28 | w := exampleWriter{NewXMLWriter(), t}
29 | util.ProcessExampleLogs(t, "Send:", func(line string) {
30 | w.Reset()
31 | require.NoError(t, ProcessXMLMessage(line, w), line)
32 | util.CompareLines(t, line, w.String())
33 | })
34 | }
35 |
--------------------------------------------------------------------------------
/cmd/pimboo-server/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "context"
5 | "flag"
6 | "log"
7 |
8 | "github.com/dnovikoff/tenhou/cmd/pimboo-server/game"
9 | "github.com/dnovikoff/tenhou/network"
10 | )
11 |
12 | var addrFlag = flag.String("addr", ":10080", "listen addr")
13 |
14 | func checkError(err error) {
15 | if err == nil {
16 | return
17 | }
18 | log.Fatal(err)
19 | }
20 |
21 | func main() {
22 | flag.Parse()
23 | ln := network.NewListener()
24 | ln.OnError = func(err error) {
25 | checkError(err)
26 | }
27 | ln.Handler = func(c network.XMLConnection) {
28 | log.Printf("New game connection")
29 | game := game.NewGame(c)
30 | game.Run()
31 | c.Close()
32 | log.Printf("Game connection closed")
33 | }
34 | log.Printf("Starting server on addr '%v'", *addrFlag)
35 | err := ln.ListenAndServe(context.Background(), "tcp", *addrFlag)
36 | checkError(err)
37 | }
38 |
--------------------------------------------------------------------------------
/tools/tentool/logs/cmd_remove_index.go:
--------------------------------------------------------------------------------
1 | package logs
2 |
3 | import (
4 | "fmt"
5 | "strings"
6 |
7 | "github.com/dnovikoff/tenhou/tools/tentool/utils"
8 | )
9 |
10 | func RemoveIndex(prefix string) {
11 | index, err := LoadIndex()
12 | utils.Check(err)
13 | removed := 0
14 |
15 | index.data.Files = removeIndex(index.data.Files, prefix, &removed)
16 | for _, v := range index.data.Zips {
17 | v.Files = removeIndex(v.Files, prefix, &removed)
18 | }
19 | fmt.Printf("Removed %v links. New database size: %v\n", removed, index.Len())
20 | utils.Check(index.Save())
21 | }
22 |
23 | func removeIndex(infos []*FileInfo, prefix string, removed *int) []*FileInfo {
24 | next := make([]*FileInfo, 0, len(infos))
25 | for _, v := range infos {
26 | if !strings.HasPrefix(v.ID, prefix) {
27 | next = append(next, v)
28 | } else {
29 | *removed++
30 | }
31 | }
32 | return next
33 | }
34 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yaml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on: [push, pull_request]
3 | jobs:
4 | build:
5 | name: Build
6 | runs-on: ubuntu-latest
7 | steps:
8 | - name: Set up Go 1.24.3
9 | uses: actions/setup-go@v1
10 | with:
11 | go-version: 1.24.3
12 |
13 | - name: Check out source code
14 | uses: actions/checkout@v1
15 |
16 | - name: Generate
17 | env:
18 | GOPROXY: "off"
19 | run: make generate
20 |
21 | - name: Build
22 | env:
23 | GOPROXY: "off"
24 | run: make build
25 |
26 | - name: Test
27 | env:
28 | GOPROXY: "off"
29 | run: make testcover
30 |
31 | - name: Upload coverage to Codecov
32 | uses: codecov/codecov-action@v1
33 | with:
34 | file: ./coverage.txt
35 | fail_ci_if_error: true
36 | verbose: false
37 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/dnovikoff/tenhou
2 |
3 | go 1.24.3
4 |
5 | require (
6 | github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500
7 | github.com/dnovikoff/tempai-core v0.0.0-20250525213436-fc253e399aa7
8 | github.com/facebookgo/stackerr v0.0.0-20150612192056-c2fcf88613f4
9 | github.com/golang/protobuf v1.5.4
10 | github.com/satori/go.uuid v1.2.0
11 | github.com/spf13/cobra v1.9.1
12 | github.com/stretchr/testify v1.10.0
13 | go.uber.org/multierr v1.11.0
14 | google.golang.org/protobuf v1.36.6
15 | gopkg.in/yaml.v2 v2.4.0
16 | )
17 |
18 | require (
19 | github.com/davecgh/go-spew v1.1.1 // indirect
20 | github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect
21 | github.com/inconshreveable/mousetrap v1.1.0 // indirect
22 | github.com/pmezard/go-difflib v1.0.0 // indirect
23 | github.com/spf13/pflag v1.0.6 // indirect
24 | gopkg.in/yaml.v3 v3.0.1 // indirect
25 | )
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # About
2 |
3 | [](https://github.com/dnovikoff/tenhou/actions?query=workflow%3ACI)
4 | [](https://codecov.io/gh/dnovikoff/tenhou)
5 | [](https://goreportcard.com/report/github.com/dnovikoff/tenhou)
6 |
7 | golang package for working with tenhou net logs and protocol
8 |
9 | This package contains functions for parsing/generating:
10 | 1. Log files
11 | 2. Client messages
12 | 3. Server messages
13 |
14 | ## Proxy logging server
15 | See documentation [here](cmd/tenhou-proxy/README.md)
16 |
17 | ## Pimbooo example server
18 | See documentation [here](cmd/pimboo-server/README.md)
19 |
20 | ## Tenhou stats and log downloader
21 | See documentation [here](tools/tentool/README.md)
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/yaku/limit_string.go:
--------------------------------------------------------------------------------
1 | // Code generated by "stringer -type=Limit"; DO NOT EDIT.
2 |
3 | package yaku
4 |
5 | import "strconv"
6 |
7 | func _() {
8 | // An "invalid array index" compiler error signifies that the constant values have changed.
9 | // Re-run the stringer command to generate them again.
10 | var x [1]struct{}
11 | _ = x[LimitNone-0]
12 | _ = x[LimitMangan-1]
13 | _ = x[LimitHaneman-2]
14 | _ = x[LimitBaiman-3]
15 | _ = x[LimitSanbaiman-4]
16 | _ = x[LimitYakuman-5]
17 | }
18 |
19 | const _Limit_name = "LimitNoneLimitManganLimitHanemanLimitBaimanLimitSanbaimanLimitYakuman"
20 |
21 | var _Limit_index = [...]uint8{0, 9, 20, 32, 43, 57, 69}
22 |
23 | func (i Limit) String() string {
24 | if i < 0 || i >= Limit(len(_Limit_index)-1) {
25 | return "Limit(" + strconv.FormatInt(int64(i), 10) + ")"
26 | }
27 | return _Limit_name[_Limit_index[i]:_Limit_index[i+1]]
28 | }
29 |
--------------------------------------------------------------------------------
/parser/seed.go:
--------------------------------------------------------------------------------
1 | package parser
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/facebookgo/stackerr"
7 |
8 | "github.com/dnovikoff/tempai-core/score"
9 | "github.com/dnovikoff/tenhou/tbase"
10 | "github.com/dnovikoff/tenhou/util"
11 | )
12 |
13 | func ParseSeed(in string) (ret tbase.Seed, err error) {
14 | seed := tbase.IntList(in)
15 | if len(seed) != 6 {
16 | err = stackerr.Newf("Expected 6 elements for seed")
17 | return
18 | }
19 | ret.RoundNumber = seed[0]
20 | ret.Honba = score.Honba(seed[1])
21 | ret.Sticks = score.RiichiSticks(seed[2])
22 | ret.Dice = [2]int{seed[3], seed[4]}
23 | ret.Indicator = util.InstanceFromTenhou(seed[5])
24 | return
25 | }
26 |
27 | func SeedString(seed *tbase.Seed) string {
28 | return fmt.Sprintf("%d,%d,%d,%d,%d,%d",
29 | seed.RoundNumber,
30 | seed.Honba,
31 | seed.Sticks,
32 | seed.Dice[0],
33 | seed.Dice[1],
34 | util.InstanceToTenhou(seed.Indicator),
35 | )
36 | }
37 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go:
--------------------------------------------------------------------------------
1 | //go:build testify_yaml_custom && !testify_yaml_fail && !testify_yaml_default
2 | // +build testify_yaml_custom,!testify_yaml_fail,!testify_yaml_default
3 |
4 | // Package yaml is an implementation of YAML functions that calls a pluggable implementation.
5 | //
6 | // This implementation is selected with the testify_yaml_custom build tag.
7 | //
8 | // go test -tags testify_yaml_custom
9 | //
10 | // This implementation can be used at build time to replace the default implementation
11 | // to avoid linking with [gopkg.in/yaml.v3].
12 | //
13 | // In your test package:
14 | //
15 | // import assertYaml "github.com/stretchr/testify/assert/yaml"
16 | //
17 | // func init() {
18 | // assertYaml.Unmarshal = func (in []byte, out interface{}) error {
19 | // // ...
20 | // return nil
21 | // }
22 | // }
23 | package yaml
24 |
25 | var Unmarshal func(in []byte, out interface{}) error
26 |
--------------------------------------------------------------------------------
/cmd/pimboo-server/README.md:
--------------------------------------------------------------------------------
1 | ## pimbooo example server
2 | Pimboo (Pin-Man-Bamboo) is a small example server for a game of two players.
3 | The server is created in demonstration purposes only and does not aim for a production.
4 |
5 | Download example server
6 | ```
7 | go get -u github.com/dnovikoff/tenhou/cmd/pimboo-server
8 | ```
9 |
10 | Run application
11 | ```
12 | $GOPATH/bin/pimboo-server
13 | ```
14 |
15 | Add to your `hosts` file
16 | ```
17 | 127.0.0.1 b.mjv.jp
18 | ```
19 |
20 | 1. Login into flash client http://tenhou.net/0/ .
21 | 2. Click on any lobby
22 | 3. See start of the game
23 |
24 | 
25 |
26 | The server suggests Ron on any opponent drop and Tsumo on any take.
27 | If you call a Noten-agari, a Furiten-Ron or agari on a wrong tile, you will pay a penalty.
28 |
29 | The game continues until one of the opponents will drop under zero points.
--------------------------------------------------------------------------------
/tools/tentool/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "net/http"
7 | _ "net/http/pprof"
8 | "os"
9 | "runtime/pprof"
10 |
11 | "github.com/spf13/cobra"
12 |
13 | "github.com/dnovikoff/tenhou/tools/tentool/logs"
14 | "github.com/dnovikoff/tenhou/tools/tentool/stats"
15 | )
16 |
17 | func main() {
18 | cpuProfile := os.Getenv("CPUPROFILE")
19 | httpProfile := os.Getenv("HTTPPROFILE")
20 | if cpuProfile != "" {
21 | f, err := os.Create(cpuProfile)
22 | if err != nil {
23 | log.Fatal(err)
24 | }
25 | pprof.StartCPUProfile(f)
26 | defer func() {
27 | pprof.StopCPUProfile()
28 | f.Close()
29 | }()
30 | }
31 | if httpProfile != "" {
32 | go func() {
33 | log.Println(http.ListenAndServe(httpProfile, nil))
34 | }()
35 | }
36 | rootCmd := &cobra.Command{Use: "tentool"}
37 | rootCmd.AddCommand(stats.CMD(), logs.CMD())
38 |
39 | if err := rootCmd.Execute(); err != nil {
40 | fmt.Println(err)
41 | os.Exit(1)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/vendor/github.com/inconshreveable/mousetrap/README.md:
--------------------------------------------------------------------------------
1 | # mousetrap
2 |
3 | mousetrap is a tiny library that answers a single question.
4 |
5 | On a Windows machine, was the process invoked by someone double clicking on
6 | the executable file while browsing in explorer?
7 |
8 | ### Motivation
9 |
10 | Windows developers unfamiliar with command line tools will often "double-click"
11 | the executable for a tool. Because most CLI tools print the help and then exit
12 | when invoked without arguments, this is often very frustrating for those users.
13 |
14 | mousetrap provides a way to detect these invocations so that you can provide
15 | more helpful behavior and instructions on how to run the CLI tool. To see what
16 | this looks like, both from an organizational and a technical perspective, see
17 | https://inconshreveable.com/09-09-2014/sweat-the-small-stuff/
18 |
19 | ### The interface
20 |
21 | The library exposes a single interface:
22 |
23 | func StartedByExplorer() (bool)
24 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/yaku/fu_string.go:
--------------------------------------------------------------------------------
1 | // Code generated by "stringer -type=Fu"; DO NOT EDIT.
2 |
3 | package yaku
4 |
5 | import "strconv"
6 |
7 | func _() {
8 | // An "invalid array index" compiler error signifies that the constant values have changed.
9 | // Re-run the stringer command to generate them again.
10 | var x [1]struct{}
11 | _ = x[FuNone-0]
12 | _ = x[FuBase-1]
13 | _ = x[FuBaseClosedRon-2]
14 | _ = x[FuBase7-3]
15 | _ = x[FuSet-4]
16 | _ = x[FuTsumo-5]
17 | _ = x[FuMeld-6]
18 | _ = x[FuNoOpenFu-7]
19 | _ = x[FuBadWait-8]
20 | _ = x[FuPair-9]
21 | }
22 |
23 | const _Fu_name = "FuNoneFuBaseFuBaseClosedRonFuBase7FuSetFuTsumoFuMeldFuNoOpenFuFuBadWaitFuPair"
24 |
25 | var _Fu_index = [...]uint8{0, 6, 12, 27, 34, 39, 46, 52, 62, 71, 77}
26 |
27 | func (i Fu) String() string {
28 | if i < 0 || i >= Fu(len(_Fu_index)-1) {
29 | return "Fu(" + strconv.FormatInt(int64(i), 10) + ")"
30 | }
31 | return _Fu_name[_Fu_index[i]:_Fu_index[i+1]]
32 | }
33 |
--------------------------------------------------------------------------------
/tools/tentool/utils/gzfile.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "compress/gzip"
5 | "encoding/json"
6 | "os"
7 | )
8 |
9 | type JSONGZFile struct {
10 | Path string
11 | Pretty bool
12 | }
13 |
14 | func (f *JSONGZFile) Load(out interface{}) error {
15 | file, err := os.Open(f.fileName())
16 | if err != nil {
17 | return err
18 | }
19 | defer file.Close()
20 | gz, err := gzip.NewReader(file)
21 | if err != nil {
22 | return err
23 | }
24 | defer gz.Close()
25 | return json.NewDecoder(gz).Decode(out)
26 | }
27 |
28 | func (f *JSONGZFile) fileName() string {
29 | return f.Path + ".gz"
30 | }
31 |
32 | func (f *JSONGZFile) Save(data interface{}) (err error) {
33 | file, err := CreateFile(f.fileName())
34 | if err != nil {
35 | return
36 | }
37 | defer file.CommitOnSuccess(&err)
38 | gz := gzip.NewWriter(file)
39 | defer gz.Close()
40 | enc := json.NewEncoder(gz)
41 | if f.Pretty {
42 | enc.SetIndent("", " ")
43 | }
44 | err = enc.Encode(data)
45 | return
46 | }
47 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/require/doc.go:
--------------------------------------------------------------------------------
1 | // Package require implements the same assertions as the `assert` package but
2 | // stops test execution when a test fails.
3 | //
4 | // # Example Usage
5 | //
6 | // The following is a complete example using require in a standard test function:
7 | //
8 | // import (
9 | // "testing"
10 | // "github.com/stretchr/testify/require"
11 | // )
12 | //
13 | // func TestSomething(t *testing.T) {
14 | //
15 | // var a string = "Hello"
16 | // var b string = "Hello"
17 | //
18 | // require.Equal(t, a, b, "The two words should be the same.")
19 | //
20 | // }
21 | //
22 | // # Assertions
23 | //
24 | // The `require` package have same global functions as in the `assert` package,
25 | // but instead of returning a boolean result they call `t.FailNow()`.
26 | //
27 | // Every assertion function also takes an optional string message as the final argument,
28 | // allowing custom error messages to be appended to the message the assertion method outputs.
29 | package require
30 |
--------------------------------------------------------------------------------
/tools/tentool/utils/tracker.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import "io"
4 |
5 | type Tracker interface {
6 | Start(total int64)
7 | Write(bytes int)
8 | Done(total int64, err error)
9 | }
10 |
11 | func newWriteTracker(f ...Tracker) *writeTracker {
12 | return &writeTracker{f: f}
13 | }
14 |
15 | type writeTracker struct {
16 | w io.Writer
17 | total int64
18 | f []Tracker
19 | }
20 |
21 | func (w *writeTracker) add(f Tracker) *writeTracker {
22 | w.f = append(w.f, f)
23 | return w
24 | }
25 |
26 | func (w *writeTracker) attach(x io.Writer, total int64) {
27 | w.w = x
28 | if total < 0 {
29 | total = 0
30 | }
31 | for _, v := range w.f {
32 | v.Start(total)
33 | }
34 | }
35 |
36 | func (w *writeTracker) done(written int64, err error) error {
37 | for _, v := range w.f {
38 | v.Done(written, err)
39 | }
40 | return err
41 | }
42 |
43 | func (w *writeTracker) Write(p []byte) (int, error) {
44 | n, err := w.w.Write(p)
45 | for _, v := range w.f {
46 | v.Write(n)
47 | }
48 | return n, err
49 | }
50 |
--------------------------------------------------------------------------------
/log/controller.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | import (
4 | "github.com/dnovikoff/tenhou/client"
5 | "github.com/dnovikoff/tenhou/tbase"
6 | )
7 |
8 | type Controller interface {
9 | // Should return false if not interested
10 | Open(Info) bool
11 | Close()
12 |
13 | Shuffle(Shuffle)
14 | Go(client.WithLobby)
15 | Start(client.WithDealer)
16 | Init(Init)
17 | Draw(WithOpponentAndInstance)
18 | Discard(WithOpponentAndInstance)
19 | Declare(Declare)
20 | Ryuukyoku(tbase.Ryuukyoku)
21 | Reach(client.Reach)
22 | Agari(tbase.Agari)
23 | Indicator(client.WithInstance)
24 | Disconnect(client.WithOpponent)
25 |
26 | client.UNController
27 | }
28 |
29 | type Shuffle struct {
30 | Seed string
31 | Ref string
32 | }
33 |
34 | type Declare struct {
35 | client.WithOpponent
36 | Meld tbase.Meld
37 | }
38 |
39 | type WithOpponentAndInstance struct {
40 | client.WithOpponent
41 | client.WithInstance
42 | }
43 |
44 | type Init struct {
45 | tbase.Init
46 | Hands tbase.Hands
47 | // TODO: research
48 | Shuffle string
49 | }
50 |
--------------------------------------------------------------------------------
/vendor/go.uber.org/multierr/Makefile:
--------------------------------------------------------------------------------
1 | # Directory to put `go install`ed binaries in.
2 | export GOBIN ?= $(shell pwd)/bin
3 |
4 | GO_FILES := $(shell \
5 | find . '(' -path '*/.*' -o -path './vendor' ')' -prune \
6 | -o -name '*.go' -print | cut -b3-)
7 |
8 | .PHONY: build
9 | build:
10 | go build ./...
11 |
12 | .PHONY: test
13 | test:
14 | go test -race ./...
15 |
16 | .PHONY: gofmt
17 | gofmt:
18 | $(eval FMT_LOG := $(shell mktemp -t gofmt.XXXXX))
19 | @gofmt -e -s -l $(GO_FILES) > $(FMT_LOG) || true
20 | @[ ! -s "$(FMT_LOG)" ] || (echo "gofmt failed:" | cat - $(FMT_LOG) && false)
21 |
22 | .PHONY: golint
23 | golint:
24 | @cd tools && go install golang.org/x/lint/golint
25 | @$(GOBIN)/golint ./...
26 |
27 | .PHONY: staticcheck
28 | staticcheck:
29 | @cd tools && go install honnef.co/go/tools/cmd/staticcheck
30 | @$(GOBIN)/staticcheck ./...
31 |
32 | .PHONY: lint
33 | lint: gofmt golint staticcheck
34 |
35 | .PHONY: cover
36 | cover:
37 | go test -race -coverprofile=cover.out -coverpkg=./... -v ./...
38 | go tool cover -html=cover.out -o cover.html
39 |
--------------------------------------------------------------------------------
/tools/tentool/stats/parse_test.go:
--------------------------------------------------------------------------------
1 | package stats
2 |
3 | import (
4 | "io/ioutil"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/assert"
8 | "github.com/stretchr/testify/require"
9 | )
10 |
11 | func TestParseMainPage(t *testing.T) {
12 | assert.Equal(t, []string{
13 | "scraw2006.zip",
14 | "scraw2007.zip",
15 | "scraw2008.zip",
16 | "scraw2009.zip",
17 | "scraw2010.zip",
18 | "scraw2011.zip",
19 | "scraw2012.zip",
20 | "scraw2013.zip",
21 | "scraw2014.zip",
22 | "scraw2015.zip",
23 | "scraw2016.zip",
24 | "scraw2017.zip",
25 | }, ParseMain(loadTestData(t, "raw.html")))
26 | }
27 |
28 | func TestParseList(t *testing.T) {
29 | assert.Equal(t, []ListItem{
30 | {File: "sca20180926.log.gz", Size: 35919},
31 | {File: "sca20180927.log.gz", Size: 33557},
32 | {File: "sca20180928.log.gz", Size: 35839},
33 | }, MustParseList(loadTestData(t, "list.js")))
34 | }
35 |
36 | func loadTestData(t require.TestingT, filename string) string {
37 | data, err := ioutil.ReadFile("test_data/" + filename)
38 | require.NoError(t, err)
39 | return string(data)
40 | }
41 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/cobra/Makefile:
--------------------------------------------------------------------------------
1 | BIN="./bin"
2 | SRC=$(shell find . -name "*.go")
3 |
4 | ifeq (, $(shell which golangci-lint))
5 | $(warning "could not find golangci-lint in $(PATH), run: curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh")
6 | endif
7 |
8 | .PHONY: fmt lint test install_deps clean
9 |
10 | default: all
11 |
12 | all: fmt test
13 |
14 | fmt:
15 | $(info ******************** checking formatting ********************)
16 | @test -z $(shell gofmt -l $(SRC)) || (gofmt -d $(SRC); exit 1)
17 |
18 | lint:
19 | $(info ******************** running lint tools ********************)
20 | golangci-lint run -v
21 |
22 | test: install_deps
23 | $(info ******************** running tests ********************)
24 | go test -v ./...
25 |
26 | richtest: install_deps
27 | $(info ******************** running tests with kyoh86/richgo ********************)
28 | richgo test -v ./...
29 |
30 | install_deps:
31 | $(info ******************** downloading dependencies ********************)
32 | go get -v ./...
33 |
34 | clean:
35 | rm -rf $(BIN)
36 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/genid/field_mask_gen.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Code generated by generate-protos. DO NOT EDIT.
6 |
7 | package genid
8 |
9 | import (
10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect"
11 | )
12 |
13 | const File_google_protobuf_field_mask_proto = "google/protobuf/field_mask.proto"
14 |
15 | // Names for google.protobuf.FieldMask.
16 | const (
17 | FieldMask_message_name protoreflect.Name = "FieldMask"
18 | FieldMask_message_fullname protoreflect.FullName = "google.protobuf.FieldMask"
19 | )
20 |
21 | // Field names for google.protobuf.FieldMask.
22 | const (
23 | FieldMask_Paths_field_name protoreflect.Name = "paths"
24 |
25 | FieldMask_Paths_field_fullname protoreflect.FullName = "google.protobuf.FieldMask.paths"
26 | )
27 |
28 | // Field numbers for google.protobuf.FieldMask.
29 | const (
30 | FieldMask_Paths_field_number protoreflect.FieldNumber = 1
31 | )
32 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/init_opaque.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package internal_gengo
6 |
7 | import "google.golang.org/protobuf/types/gofeaturespb"
8 |
9 | func (m *messageInfo) isOpen() bool {
10 | return m.Message.APILevel == gofeaturespb.GoFeatures_API_OPEN
11 | }
12 |
13 | func (m *messageInfo) isHybrid() bool {
14 | return m.Message.APILevel == gofeaturespb.GoFeatures_API_HYBRID
15 | }
16 |
17 | func (m *messageInfo) isOpaque() bool {
18 | return m.Message.APILevel == gofeaturespb.GoFeatures_API_OPAQUE
19 | }
20 |
21 | func opaqueNewEnumInfoHook(f *fileInfo, e *enumInfo) {
22 | if f.File.APILevel != gofeaturespb.GoFeatures_API_OPEN {
23 | e.genJSONMethod = false
24 | e.genRawDescMethod = false
25 | }
26 | }
27 |
28 | func opaqueNewMessageInfoHook(f *fileInfo, m *messageInfo) {
29 | if !m.isOpen() {
30 | m.genRawDescMethod = false
31 | m.genExtRangeMethod = false
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/server/controller.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/tile"
5 | "github.com/dnovikoff/tenhou/tbase"
6 | )
7 |
8 | type Answer int
9 |
10 | const (
11 | AnswerSkip Answer = iota
12 | AnswerPon // 1
13 | AnswerOpenedKan // 2
14 | AnswerChi // 3
15 | AnswerClosedKan // 4
16 | AnswerChankan // 5
17 | AnswerRon // 6
18 | AnswerTsumo // 7
19 | Answer8 // What is 8???
20 | AnswerDraw // 9
21 | AnswerSanmaDora // 10
22 | )
23 |
24 | // This is how server looks from client point of view
25 | type Controller interface {
26 | Hello(name string, tid string, sex tbase.Sex)
27 | Auth(value string)
28 | // TODO: research values
29 | // Could be both big and small
30 | RequestLobbyStatus(v, V int) // PXR
31 | Join(lobbyNumber int, lobbyType int, rejoin bool)
32 | CancelJoin()
33 | Drop(t tile.Instance)
34 | Call(a Answer, tiles tile.Instances)
35 | Reach(t tile.Instance)
36 | Ping() // Z
37 | GoOK()
38 | NextReady()
39 | Bye()
40 | Chat(message string)
41 | }
42 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/score/rules.go:
--------------------------------------------------------------------------------
1 | package score
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/yaku"
5 | )
6 |
7 | type Money int
8 |
9 | type Rules interface {
10 | ManganRound() bool
11 | KazoeYakuman() bool
12 | IsDoubleYakuman(yaku.Yakuman) bool
13 | YakumanSum() bool
14 |
15 | Honba() Money
16 | }
17 |
18 | type RulesStruct struct {
19 | IsManganRound bool
20 | IsKazoeYakuman bool
21 | DoubleYakumans map[yaku.Yakuman]bool
22 | IsYakumanSum bool
23 |
24 | HonbaValue Money
25 | }
26 |
27 | var _ Rules = &RulesStruct{}
28 |
29 | func (r *RulesStruct) ManganRound() bool {
30 | return r.IsManganRound
31 | }
32 |
33 | func (r *RulesStruct) KazoeYakuman() bool {
34 | return r.IsKazoeYakuman
35 | }
36 |
37 | func (r *RulesStruct) IsDoubleYakuman(y yaku.Yakuman) bool {
38 | return r.DoubleYakumans[y]
39 | }
40 |
41 | func (r *RulesStruct) YakumanSum() bool {
42 | return r.IsYakumanSum
43 | }
44 |
45 | func (r *RulesStruct) Honba() Money {
46 | return r.HonbaValue
47 | }
48 |
49 | func GetHonbaMoney(r Rules, honba Honba) Money {
50 | return Money(honba) * r.Honba()
51 | }
52 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/yaku/win.go:
--------------------------------------------------------------------------------
1 | package yaku
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/compact"
5 | "github.com/dnovikoff/tempai-core/hand/calc"
6 | "github.com/dnovikoff/tempai-core/hand/tempai"
7 | )
8 |
9 | func Win(results *tempai.TempaiResults, ctx *Context, declaredTiles compact.Instances) *Result {
10 | isRon := ctx.isRon()
11 | top := 0
12 | var ret *Result
13 | for _, v := range results.Results {
14 | win := v.Last.Complete(ctx.Tile.Tile())
15 | if win == nil {
16 | continue
17 | }
18 | if isRon {
19 | win = calc.Open(win)
20 | }
21 | args := &args{
22 | ctx: ctx,
23 | result: v,
24 | hand: results.Hand,
25 | declared: declared{
26 | melds: results.Declared,
27 | tiles: declaredTiles,
28 | },
29 | win: win,
30 | }
31 | res := calculate(args)
32 | if res == nil {
33 | continue
34 | }
35 | if len(res.Yakumans) > 0 {
36 | top = 14
37 | return res
38 | }
39 | sum := int(res.Fus.Sum()) + int(res.Yaku.Sum()*1000)
40 | if sum > top && sum > 1000 {
41 | ret = res
42 | top = sum
43 | }
44 | }
45 | return ret
46 | }
47 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Dmitry Novikov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/util/async_writer.go:
--------------------------------------------------------------------------------
1 | package util
2 |
3 | import (
4 | "context"
5 | "errors"
6 | "sync"
7 | )
8 |
9 | const DefaultChannelSize = 1024
10 |
11 | type AsyncWriter struct {
12 | writeChan chan string
13 | WriteCallback func(context.Context, string) error
14 | }
15 |
16 | func NewAsyncWriter(channelSize int) *AsyncWriter {
17 | return &AsyncWriter{writeChan: make(chan string, channelSize)}
18 | }
19 |
20 | func (w *AsyncWriter) run(ctx context.Context) {
21 | ctx, cancel := context.WithCancel(ctx)
22 | defer cancel()
23 | for message := range w.writeChan {
24 | err := w.WriteCallback(ctx, message)
25 | if err != nil {
26 | return
27 | }
28 | }
29 | }
30 |
31 | func (w *AsyncWriter) Close() {
32 | close(w.writeChan)
33 | }
34 |
35 | func (w *AsyncWriter) Start(ctx context.Context) func() {
36 | var wg sync.WaitGroup
37 | wg.Add(1)
38 | go func() {
39 | w.run(ctx)
40 | wg.Done()
41 | }()
42 | return wg.Wait
43 | }
44 |
45 | func (w *AsyncWriter) WriteString(message string) error {
46 | select {
47 | case w.writeChan <- message:
48 | default:
49 | return errors.New("Channel is full")
50 | }
51 | return nil
52 | }
53 |
--------------------------------------------------------------------------------
/tools/tentool/utils/interactive_writer.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 | "io"
7 | "strings"
8 | )
9 |
10 | type InteractiveWriter struct {
11 | w io.Writer
12 | buf *bytes.Buffer
13 | lastSize int
14 | }
15 |
16 | func NewInteractiveWriter(w io.Writer) *InteractiveWriter {
17 | return &InteractiveWriter{w: w, buf: &bytes.Buffer{}}
18 | }
19 |
20 | func (w *InteractiveWriter) Printf(format string, args ...interface{}) (int, error) {
21 | lastString := w.buf.String()
22 | w.buf.Reset()
23 | fmt.Fprintf(w.buf, format, args...)
24 | if lastString == w.buf.String() {
25 | return w.buf.Len(), nil
26 | }
27 | return fmt.Fprint(w.w, w.fixString(w.buf.String()))
28 | }
29 |
30 | func (w *InteractiveWriter) Println(args ...interface{}) (int, error) {
31 | w.lastSize = 0
32 | return fmt.Fprintln(w.w, args...)
33 | }
34 |
35 | func (w *InteractiveWriter) fixString(str string) string {
36 | size := len(str)
37 | if w.lastSize != 0 {
38 | str = "\r" + str
39 | }
40 | diff := w.lastSize - size
41 | if diff > 0 {
42 | str += strings.Repeat(" ", diff)
43 | }
44 | w.lastSize = size
45 | return str
46 | }
47 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/genid/source_context_gen.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Code generated by generate-protos. DO NOT EDIT.
6 |
7 | package genid
8 |
9 | import (
10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect"
11 | )
12 |
13 | const File_google_protobuf_source_context_proto = "google/protobuf/source_context.proto"
14 |
15 | // Names for google.protobuf.SourceContext.
16 | const (
17 | SourceContext_message_name protoreflect.Name = "SourceContext"
18 | SourceContext_message_fullname protoreflect.FullName = "google.protobuf.SourceContext"
19 | )
20 |
21 | // Field names for google.protobuf.SourceContext.
22 | const (
23 | SourceContext_FileName_field_name protoreflect.Name = "file_name"
24 |
25 | SourceContext_FileName_field_fullname protoreflect.FullName = "google.protobuf.SourceContext.file_name"
26 | )
27 |
28 | // Field numbers for google.protobuf.SourceContext.
29 | const (
30 | SourceContext_FileName_field_number protoreflect.FieldNumber = 1
31 | )
32 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/hand/calc/counter_block.go:
--------------------------------------------------------------------------------
1 | package calc
2 |
3 | type counterBlock int64
4 |
5 | func (b *counterBlock) set(i uint, c int) {
6 | *b = (*b) & (^(counterBlock(7) << (i * 3)))
7 | *b = (*b) | counterBlock((c&7)<<(i*3))
8 | }
9 |
10 | func (b *counterBlock) get(i uint) int {
11 | return (int(*b) >> (i * 3)) & 7
12 | }
13 |
14 | func (b *counterBlock) invert(cnt uint) {
15 | for i := uint(0); i < cnt; i++ {
16 | b.set(i, 4-b.get(i))
17 | }
18 | }
19 |
20 | func (b *counterBlock) dec(i uint, c int) bool {
21 | c = b.get(i) - c
22 | if c < 0 {
23 | return false
24 | }
25 | b.set(i, c)
26 | return true
27 | }
28 |
29 | func (b *counterBlock) dec2(i uint, shift uint) bool {
30 | x1 := b.get(i)
31 | x2 := b.get(i + shift)
32 | if x1 < 1 || x2 < 1 {
33 | return false
34 | }
35 | b.set(i, x1-1)
36 | b.set(i+shift, x2-1)
37 | return true
38 | }
39 |
40 | func (b *counterBlock) dec3(i uint) bool {
41 | x1 := b.get(i)
42 | x2 := b.get(i + 1)
43 | x3 := b.get(i + 2)
44 | if x1 < 1 || x2 < 1 || x3 < 1 {
45 | return false
46 | }
47 | b.set(i, x1-1)
48 | b.set(i+1, x2-1)
49 | b.set(i+2, x3-1)
50 | return true
51 | }
52 |
--------------------------------------------------------------------------------
/vendor/go.uber.org/multierr/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017-2021 Uber Technologies, Inc.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/vendor/github.com/satori/go.uuid/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2013-2018 by Maxim Bublis
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/tools/tentool/logs/cmd_get.go:
--------------------------------------------------------------------------------
1 | package logs
2 |
3 | import (
4 | "archive/zip"
5 | "compress/gzip"
6 | "io"
7 | "log"
8 | "os"
9 |
10 | "github.com/dnovikoff/tenhou/tools/tentool/utils"
11 | )
12 |
13 | func cmdGet(id string) {
14 | parsedIds := ParseIDs(id)
15 | if len(parsedIds) == 1 {
16 | id = parsedIds[0]
17 | }
18 | index, err := LoadIndex()
19 | utils.Check(err)
20 | info := index.Get(id)
21 | if info.IsInsideZip() {
22 | zf, err := zip.OpenReader(fileName(info.parent.File))
23 | utils.Check(err)
24 | defer zf.Close()
25 | for _, v := range zf.File {
26 | if v.Name != info.File {
27 | continue
28 | }
29 | f, err := v.Open()
30 | utils.Check(err)
31 | defer f.Close()
32 | io.Copy(os.Stdout, f)
33 | return
34 | }
35 | log.Fatalf("File '%v' not found in archive '%v'", info.File, info.parent.File)
36 | } else if info.File != "" {
37 | f, err := os.Open(fileName(info.File))
38 | utils.Check(err)
39 | gz, err := gzip.NewReader(f)
40 | utils.Check(err)
41 | io.Copy(os.Stdout, gz)
42 | utils.Check(gz.Close())
43 | utils.Check(f.Close())
44 | } else {
45 | log.Fatalf("Log with id '%v' not found in database", id)
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Dmitry Novikov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vendor/github.com/c2h5oh/datasize/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Maciej Lisiewski
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/network/examples/f5182_2018-01-22_12_36_49.log:
--------------------------------------------------------------------------------
1 | Send:
2 | Get:
3 | Send:
4 | Send:
5 | Get:
6 | Send:
7 | Send:
8 | Send:
9 | Get:
10 | Send:
11 | Get:
12 | Send:
13 | Send:
14 |
--------------------------------------------------------------------------------
/tools/tentool/utils/options.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "compress/gzip"
5 | "io"
6 | "net/http"
7 | )
8 |
9 | const (
10 | UserAgent = "TenToolBot (+https://github.com/dnovikoff/tenhou/tools/tentool)"
11 | )
12 |
13 | type downloader struct {
14 | tracker *writeTracker
15 | compressor func(io.Writer) io.WriteCloser
16 | client *http.Client
17 | userAgent string
18 | }
19 |
20 | type Option func(*downloader)
21 |
22 | func AddTracker(f Tracker) Option {
23 | return func(x *downloader) {
24 | x.tracker.add(f)
25 | }
26 | }
27 |
28 | func Client(c *http.Client) Option {
29 | return func(x *downloader) {
30 | x.client = c
31 | }
32 | }
33 |
34 | func Compressor(f func(io.Writer) io.WriteCloser) Option {
35 | return func(x *downloader) {
36 | x.compressor = f
37 | }
38 | }
39 |
40 | func GZIP() Option {
41 | return Compressor(func(w io.Writer) io.WriteCloser {
42 | return gzip.NewWriter(w)
43 | })
44 | }
45 |
46 | func NewDownloader(opts ...Option) *downloader {
47 | x := &downloader{
48 | client: &http.Client{},
49 | tracker: newWriteTracker(),
50 | userAgent: UserAgent,
51 | }
52 | for _, v := range opts {
53 | v(x)
54 | }
55 | return x
56 | }
57 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/score/rules_prefefined.go:
--------------------------------------------------------------------------------
1 | package score
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/yaku"
5 | )
6 |
7 | func RulesEMA() *RulesStruct {
8 | return &RulesStruct{
9 | IsManganRound: false,
10 | IsKazoeYakuman: false,
11 | IsYakumanSum: false,
12 | HonbaValue: 100,
13 | }
14 | }
15 |
16 | func RulesTenhou() *RulesStruct {
17 | return &RulesStruct{
18 | IsManganRound: false,
19 | IsKazoeYakuman: true,
20 | IsYakumanSum: true,
21 | HonbaValue: 100,
22 | }
23 | }
24 |
25 | func RulesJPMLA() *RulesStruct {
26 | return &RulesStruct{
27 | IsManganRound: false,
28 | IsKazoeYakuman: false,
29 | IsYakumanSum: false,
30 | HonbaValue: 100,
31 | }
32 | }
33 |
34 | func RulesJPMLB() *RulesStruct {
35 | return &RulesStruct{
36 | IsManganRound: true,
37 | IsKazoeYakuman: false,
38 | IsYakumanSum: false,
39 | HonbaValue: 100,
40 | }
41 | }
42 |
43 | func DefaultDoubleYakumans() map[yaku.Yakuman]bool {
44 | return map[yaku.Yakuman]bool{
45 | yaku.YakumanChuurenpooto9: true,
46 | yaku.YakumanKokushi13: true,
47 | yaku.YakumanSuuankouTanki: true,
48 | yaku.YakumanDaisuushi: true,
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2012-2020 Mat Ryer, Tyler Bunnell and contributors.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/genid/any_gen.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Code generated by generate-protos. DO NOT EDIT.
6 |
7 | package genid
8 |
9 | import (
10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect"
11 | )
12 |
13 | const File_google_protobuf_any_proto = "google/protobuf/any.proto"
14 |
15 | // Names for google.protobuf.Any.
16 | const (
17 | Any_message_name protoreflect.Name = "Any"
18 | Any_message_fullname protoreflect.FullName = "google.protobuf.Any"
19 | )
20 |
21 | // Field names for google.protobuf.Any.
22 | const (
23 | Any_TypeUrl_field_name protoreflect.Name = "type_url"
24 | Any_Value_field_name protoreflect.Name = "value"
25 |
26 | Any_TypeUrl_field_fullname protoreflect.FullName = "google.protobuf.Any.type_url"
27 | Any_Value_field_fullname protoreflect.FullName = "google.protobuf.Any.value"
28 | )
29 |
30 | // Field numbers for google.protobuf.Any.
31 | const (
32 | Any_TypeUrl_field_number protoreflect.FieldNumber = 1
33 | Any_Value_field_number protoreflect.FieldNumber = 2
34 | )
35 |
--------------------------------------------------------------------------------
/log/null_controller.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | import (
4 | "github.com/dnovikoff/tenhou/client"
5 | "github.com/dnovikoff/tenhou/tbase"
6 | )
7 |
8 | type NullController struct{}
9 |
10 | var _ Controller = NullController{}
11 |
12 | func (NullController) Open(Info) bool { return true }
13 | func (NullController) Close() {}
14 | func (NullController) Shuffle(Shuffle) {}
15 | func (NullController) Go(client.WithLobby) {}
16 | func (NullController) Start(client.WithDealer) {}
17 | func (NullController) Init(Init) {}
18 | func (NullController) Draw(WithOpponentAndInstance) {}
19 | func (NullController) Discard(WithOpponentAndInstance) {}
20 | func (NullController) Declare(Declare) {}
21 | func (NullController) Ryuukyoku(tbase.Ryuukyoku) {}
22 | func (NullController) Reach(client.Reach) {}
23 | func (NullController) Agari(tbase.Agari) {}
24 | func (NullController) Indicator(client.WithInstance) {}
25 | func (NullController) Disconnect(client.WithOpponent) {}
26 | func (NullController) UserList(client.UserList) {}
27 | func (NullController) Reconnect(client.Reconnect) {}
28 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/hand/calc/meld.go:
--------------------------------------------------------------------------------
1 | package calc
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/compact"
5 | "github.com/dnovikoff/tempai-core/tile"
6 | )
7 |
8 | type Meld interface {
9 | Tile() tile.Tile
10 | Tags() Tags
11 | Waits() tile.Tiles
12 | CompactWaits() compact.Tiles
13 | // For debug
14 | Tiles() tile.Tiles
15 | Complete(t tile.Tile) Meld
16 | Extract(Counters) bool
17 | }
18 |
19 | type meld struct {
20 | tags Tags
21 | waits tile.Tiles
22 | cwaits compact.Tiles
23 | t tile.Tile
24 | tiles tile.Tiles
25 | }
26 |
27 | func (m *meld) Tags() Tags {
28 | return m.tags
29 | }
30 |
31 | func (m *meld) Complete(t tile.Tile) Meld {
32 | return nil
33 | }
34 |
35 | func (m *meld) Tile() tile.Tile {
36 | return m.t
37 | }
38 |
39 | func (m *meld) Waits() tile.Tiles {
40 | return m.waits
41 | }
42 |
43 | func (m *meld) Tiles() tile.Tiles {
44 | return m.tiles
45 | }
46 |
47 | func (m *meld) CompactWaits() compact.Tiles {
48 | return m.cwaits
49 | }
50 |
51 | type openWrapper struct {
52 | Meld
53 | }
54 |
55 | func (w openWrapper) Tags() Tags {
56 | return w.Meld.Tags() | TagOpened
57 | }
58 |
59 | func Open(m Meld) Meld {
60 | return openWrapper{m}
61 | }
62 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/flags/flags.go:
--------------------------------------------------------------------------------
1 | // Copyright 2018 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package flags provides a set of flags controlled by build tags.
6 | package flags
7 |
8 | // ProtoLegacy specifies whether to enable support for legacy functionality
9 | // such as MessageSets, and various other obscure behavior
10 | // that is necessary to maintain backwards compatibility with proto1 or
11 | // the pre-release variants of proto2 and proto3.
12 | //
13 | // This is disabled by default unless built with the "protolegacy" tag.
14 | //
15 | // WARNING: The compatibility agreement covers nothing provided by this flag.
16 | // As such, functionality may suddenly be removed or changed at our discretion.
17 | const ProtoLegacy = protoLegacy
18 |
19 | // LazyUnmarshalExtensions specifies whether to lazily unmarshal extensions.
20 | //
21 | // Lazy extension unmarshaling validates the contents of message-valued
22 | // extension fields at unmarshal time, but defers creating the message
23 | // structure until the extension is first accessed.
24 | const LazyUnmarshalExtensions = ProtoLegacy
25 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/yaku/context.go:
--------------------------------------------------------------------------------
1 | package yaku
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/base"
5 | "github.com/dnovikoff/tempai-core/tile"
6 | )
7 |
8 | // Context is createed to avoid using other game objects in calculations
9 | type Context struct {
10 | Tile tile.Instance
11 | SelfWind base.Wind
12 | RoundWind base.Wind
13 | DoraTiles tile.Tiles
14 | UraTiles tile.Tiles
15 | Rules Rules
16 | IsTsumo bool
17 | IsRiichi bool
18 | IsIpatsu bool
19 | IsDaburi bool
20 | IsLastTile bool
21 | IsRinshan bool
22 | IsFirstTake bool
23 | IsChankan bool
24 | }
25 |
26 | func (c *Context) shouldAddUras() bool {
27 | return c.IsRiichi && c.Rules.Ura()
28 | }
29 |
30 | func (c *Context) shouldAddIpatsu() bool {
31 | return c.IsIpatsu && c.Rules.Ipatsu()
32 | }
33 |
34 | func (c *Context) isRon() bool {
35 | return !c.IsTsumo
36 | }
37 |
38 | func IndicatorsToDoraTiles(in tile.Instances) tile.Tiles {
39 | return TileIndicatorsToDoraTiles(in.Tiles())
40 | }
41 |
42 | func TileIndicatorsToDoraTiles(in tile.Tiles) tile.Tiles {
43 | out := make(tile.Tiles, len(in))
44 | for k, v := range in {
45 | out[k] = v.Indicates()
46 | }
47 | return out
48 | }
49 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/proto/reset.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package proto
6 |
7 | import (
8 | "fmt"
9 |
10 | "google.golang.org/protobuf/reflect/protoreflect"
11 | )
12 |
13 | // Reset clears every field in the message.
14 | // The resulting message shares no observable memory with its previous state
15 | // other than the memory for the message itself.
16 | func Reset(m Message) {
17 | if mr, ok := m.(interface{ Reset() }); ok && hasProtoMethods {
18 | mr.Reset()
19 | return
20 | }
21 | resetMessage(m.ProtoReflect())
22 | }
23 |
24 | func resetMessage(m protoreflect.Message) {
25 | if !m.IsValid() {
26 | panic(fmt.Sprintf("cannot reset invalid %v message", m.Descriptor().FullName()))
27 | }
28 |
29 | // Clear all known fields.
30 | fds := m.Descriptor().Fields()
31 | for i := 0; i < fds.Len(); i++ {
32 | m.Clear(fds.Get(i))
33 | }
34 |
35 | // Clear extension fields.
36 | m.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {
37 | m.Clear(fd)
38 | return true
39 | })
40 |
41 | // Clear unknown fields.
42 | m.SetUnknown(nil)
43 | }
44 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/proto/wrappers.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package proto
6 |
7 | // Bool stores v in a new bool value and returns a pointer to it.
8 | func Bool(v bool) *bool { return &v }
9 |
10 | // Int32 stores v in a new int32 value and returns a pointer to it.
11 | func Int32(v int32) *int32 { return &v }
12 |
13 | // Int64 stores v in a new int64 value and returns a pointer to it.
14 | func Int64(v int64) *int64 { return &v }
15 |
16 | // Float32 stores v in a new float32 value and returns a pointer to it.
17 | func Float32(v float32) *float32 { return &v }
18 |
19 | // Float64 stores v in a new float64 value and returns a pointer to it.
20 | func Float64(v float64) *float64 { return &v }
21 |
22 | // Uint32 stores v in a new uint32 value and returns a pointer to it.
23 | func Uint32(v uint32) *uint32 { return &v }
24 |
25 | // Uint64 stores v in a new uint64 value and returns a pointer to it.
26 | func Uint64(v uint64) *uint64 { return &v }
27 |
28 | // String stores v in a new string value and returns a pointer to it.
29 | func String(v string) *string { return &v }
30 |
--------------------------------------------------------------------------------
/network/xml_connection_debug.go:
--------------------------------------------------------------------------------
1 | package network
2 |
3 | import (
4 | "context"
5 | "fmt"
6 | "io"
7 | "sync"
8 | )
9 |
10 | type xmlDebugger struct {
11 | impl XMLConnection
12 | log func(format string, args ...interface{})
13 | }
14 |
15 | func NewMutexLogger(w io.Writer) func(format string, args ...interface{}) {
16 | var m sync.Mutex
17 | return func(format string, args ...interface{}) {
18 | m.Lock()
19 | defer m.Unlock()
20 | fmt.Fprintf(w, format+"\n", args...)
21 | }
22 | }
23 |
24 | func NewXMLConnectionDebugger(impl XMLConnection, log func(format string, args ...interface{})) XMLConnection {
25 | return &xmlDebugger{impl, log}
26 | }
27 |
28 | func (d *xmlDebugger) Read(ctx context.Context) (str string, err error) {
29 | str, err = d.impl.Read(ctx)
30 | if err != nil {
31 | d.log("Get error: %v", err)
32 | } else {
33 | d.log("Get: %v", str)
34 | }
35 | return
36 | }
37 |
38 | func (d *xmlDebugger) Close() error {
39 | d.log("Close")
40 | return d.impl.Close()
41 | }
42 |
43 | // Not thread safe
44 | func (d *xmlDebugger) Write(ctx context.Context, str string) error {
45 | d.log("Send: %v", str)
46 | err := d.impl.Write(ctx, str)
47 | if err != nil {
48 | d.log("Write error: %v", err)
49 | }
50 | return err
51 | }
52 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/cobra/command_win.go:
--------------------------------------------------------------------------------
1 | // Copyright 2013-2023 The Cobra Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | //go:build windows
16 | // +build windows
17 |
18 | package cobra
19 |
20 | import (
21 | "fmt"
22 | "os"
23 | "time"
24 |
25 | "github.com/inconshreveable/mousetrap"
26 | )
27 |
28 | var preExecHookFn = preExecHook
29 |
30 | func preExecHook(c *Command) {
31 | if MousetrapHelpText != "" && mousetrap.StartedByExplorer() {
32 | c.Print(MousetrapHelpText)
33 | if MousetrapDisplayDuration > 0 {
34 | time.Sleep(MousetrapDisplayDuration)
35 | } else {
36 | c.Println("Press return to continue...")
37 | fmt.Scanln()
38 | }
39 | os.Exit(1)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/pragma/pragma.go:
--------------------------------------------------------------------------------
1 | // Copyright 2018 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package pragma provides types that can be embedded into a struct to
6 | // statically enforce or prevent certain language properties.
7 | package pragma
8 |
9 | import "sync"
10 |
11 | // NoUnkeyedLiterals can be embedded in a struct to prevent unkeyed literals.
12 | type NoUnkeyedLiterals struct{}
13 |
14 | // DoNotImplement can be embedded in an interface to prevent trivial
15 | // implementations of the interface.
16 | //
17 | // This is useful to prevent unauthorized implementations of an interface
18 | // so that it can be extended in the future for any protobuf language changes.
19 | type DoNotImplement interface{ ProtoInternal(DoNotImplement) }
20 |
21 | // DoNotCompare can be embedded in a struct to prevent comparability.
22 | type DoNotCompare [0]func()
23 |
24 | // DoNotCopy can be embedded in a struct to help prevent shallow copies.
25 | // This does not rely on a Go language feature, but rather a special case
26 | // within the vet checker.
27 | //
28 | // See https://golang.org/issues/8005.
29 | type DoNotCopy [0]sync.Mutex
30 |
--------------------------------------------------------------------------------
/network/auth.go:
--------------------------------------------------------------------------------
1 | package network
2 |
3 | import (
4 | "fmt"
5 | "strconv"
6 | "strings"
7 | )
8 |
9 | var translationTable = []int{63006, 9570, 49216, 45888, 9822, 23121, 59830, 51114, 54831, 4189, 580, 5203, 42174, 59972,
10 | 55457, 59009, 59347, 64456, 8673, 52710, 49975, 2006, 62677, 3463, 17754, 5357}
11 |
12 | func AuthAnswer(input string) (ret string, err error) {
13 | parts := strings.Split(input, "-")
14 | if len(parts) != 2 {
15 | err = fmt.Errorf("Wrong parts")
16 | return
17 | }
18 | first := parts[0]
19 | second := parts[1]
20 |
21 | if len(first) != 8 || len(second) != 8 {
22 | err = fmt.Errorf("Wrong size")
23 | return
24 | }
25 |
26 | i1, err := strconv.ParseInt("2"+first[2:8], 10, 64)
27 | if err != nil {
28 | return
29 | }
30 | i2, err := strconv.ParseInt("2"+first[7:8], 10, 64)
31 | if err != nil {
32 | return
33 | }
34 | index := i1 % (12 - i2) * 2
35 |
36 | a16, err := strconv.ParseUint(second[0:4], 16, 64)
37 | if err != nil {
38 | return
39 | }
40 | b16, err := strconv.ParseUint(second[4:8], 16, 64)
41 | if err != nil {
42 | return
43 | }
44 |
45 | a := translationTable[index] ^ int(a16)
46 | b := translationTable[index+1] ^ int(b16)
47 |
48 | ret = first + "-" + fmt.Sprintf("%2x%2x", a, b)
49 | return
50 | }
51 |
--------------------------------------------------------------------------------
/log/test_data/README.txt:
--------------------------------------------------------------------------------
1 | shuffle.xml
2 | 00a1/2009/03/17/2009031702gm-00a1-0000-336ee82a.mjlog
3 | shuffle inside INIT
4 |
5 | bye.xml
6 | File 00a1/2009/06/18/2009061806gm-00a1-0000-6d13c207.mjlog
7 | Error: Unexpected node BYE
8 | File 00a1/2009/06/18/2009061806gm-00a1-0000-6d13c207.mjlog
9 | Error: Unprocessed attributes [n1] for UN
10 |
11 | pao.xml
12 | File 00a9/2010/01/22/2010012206gm-00a9-0000-5414f3c4.mjlog
13 | Error: Unprocessed attributes [paoWho] for AGARI [&{AGARI map[paoWho:0]}]
14 |
15 | ratio.xml
16 | File 0841/2013/03/11/2013031109gm-0841-0000-0fde62c3.mjlog
17 | Error: Unprocessed attributes [ratio] for AGARI [&{AGARI map[ratio:0,1]}]
18 |
19 | TODO: find log with ron pao
20 |
21 | bug1.xml
22 | 2009022022gm-00a9-0000-cd94aac8
23 |
24 | bug2.xml
25 | 2009022103gm-00a9-0000-74c37deb
26 |
27 | bug3.xml
28 | 2009022116gm-00a9-0000-77155835
29 |
30 | bug4.xml
31 | 2009022314gm-00a9-0000-9f619d34
32 |
33 | bug5.xml
34 | 2009040322gm-00a9-0000-a911cae1
35 |
36 | bug6.xml
37 | 2009040902gm-00a9-0000-89c396a2
38 |
39 | bug7.xml
40 | 2009071622gm-00a9-0000-a6056eb1
41 |
42 | bug8.xml
43 | 2009082902gm-00a9-0000-df6a8b53
44 |
45 | bug9.xml
46 | 2009091515gm-00a9-0000-1753da1d
47 |
48 | chip.xml, ratio1.xml
49 | Seems like different calculation rules (like kiriyage mangan)
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/require/requirements.go:
--------------------------------------------------------------------------------
1 | package require
2 |
3 | // TestingT is an interface wrapper around *testing.T
4 | type TestingT interface {
5 | Errorf(format string, args ...interface{})
6 | FailNow()
7 | }
8 |
9 | type tHelper = interface {
10 | Helper()
11 | }
12 |
13 | // ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful
14 | // for table driven tests.
15 | type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{})
16 |
17 | // ValueAssertionFunc is a common function prototype when validating a single value. Can be useful
18 | // for table driven tests.
19 | type ValueAssertionFunc func(TestingT, interface{}, ...interface{})
20 |
21 | // BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful
22 | // for table driven tests.
23 | type BoolAssertionFunc func(TestingT, bool, ...interface{})
24 |
25 | // ErrorAssertionFunc is a common function prototype when validating an error value. Can be useful
26 | // for table driven tests.
27 | type ErrorAssertionFunc func(TestingT, error, ...interface{})
28 |
29 | //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require.go.tmpl -include-format-funcs"
30 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/genid/duration_gen.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Code generated by generate-protos. DO NOT EDIT.
6 |
7 | package genid
8 |
9 | import (
10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect"
11 | )
12 |
13 | const File_google_protobuf_duration_proto = "google/protobuf/duration.proto"
14 |
15 | // Names for google.protobuf.Duration.
16 | const (
17 | Duration_message_name protoreflect.Name = "Duration"
18 | Duration_message_fullname protoreflect.FullName = "google.protobuf.Duration"
19 | )
20 |
21 | // Field names for google.protobuf.Duration.
22 | const (
23 | Duration_Seconds_field_name protoreflect.Name = "seconds"
24 | Duration_Nanos_field_name protoreflect.Name = "nanos"
25 |
26 | Duration_Seconds_field_fullname protoreflect.FullName = "google.protobuf.Duration.seconds"
27 | Duration_Nanos_field_fullname protoreflect.FullName = "google.protobuf.Duration.nanos"
28 | )
29 |
30 | // Field numbers for google.protobuf.Duration.
31 | const (
32 | Duration_Seconds_field_number protoreflect.FieldNumber = 1
33 | Duration_Nanos_field_number protoreflect.FieldNumber = 2
34 | )
35 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/compact/constants.go:
--------------------------------------------------------------------------------
1 | package compact
2 |
3 | import "github.com/dnovikoff/tempai-core/tile"
4 |
5 | const (
6 | Man1 Tiles = 1 << iota
7 | Man2
8 | Man3
9 | Man4
10 | Man5
11 | Man6
12 | Man7
13 | Man8
14 | Man9
15 |
16 | Pin1
17 | Pin2
18 | Pin3
19 | Pin4
20 | Pin5
21 | Pin6
22 | Pin7
23 | Pin8
24 | Pin9
25 |
26 | Sou1
27 | Sou2
28 | Sou3
29 | Sou4
30 | Sou5
31 | Sou6
32 | Sou7
33 | Sou8
34 | Sou9
35 |
36 | East
37 | South
38 | West
39 | North
40 |
41 | White
42 | Green
43 | Red
44 |
45 | TileEnd
46 | )
47 |
48 | const (
49 | Terminal = Sou1 | Sou9 | Man1 | Man9 | Pin1 | Pin9
50 | Wind = East | South | West | North
51 | Dragon = White | Green | Red
52 |
53 | Man = Man1 | Man2 | Man3 | Man4 | Man5 | Man6 | Man7 | Man8 | Man9
54 | Pin = Pin1 | Pin2 | Pin3 | Pin4 | Pin5 | Pin6 | Pin7 | Pin8 | Pin9
55 | Sou = Sou1 | Sou2 | Sou3 | Sou4 | Sou5 | Sou6 | Sou7 | Sou8 | Sou9
56 |
57 | Sequence = Man | Pin | Sou
58 |
59 | Honor = Wind | Dragon
60 | TerminalOrHonor = Terminal | Honor
61 |
62 | AllTiles = TileEnd - 1
63 | Middle = (AllTiles ^ TerminalOrHonor) & AllTiles
64 |
65 | GreenYakuman = Sou2 | Sou3 | Sou4 | Sou6 | Sou8 | Green
66 | )
67 |
68 | // 53 is js limit for int64
69 | const _ = uint(53 - tile.TileEnd)
70 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/genid/timestamp_gen.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Code generated by generate-protos. DO NOT EDIT.
6 |
7 | package genid
8 |
9 | import (
10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect"
11 | )
12 |
13 | const File_google_protobuf_timestamp_proto = "google/protobuf/timestamp.proto"
14 |
15 | // Names for google.protobuf.Timestamp.
16 | const (
17 | Timestamp_message_name protoreflect.Name = "Timestamp"
18 | Timestamp_message_fullname protoreflect.FullName = "google.protobuf.Timestamp"
19 | )
20 |
21 | // Field names for google.protobuf.Timestamp.
22 | const (
23 | Timestamp_Seconds_field_name protoreflect.Name = "seconds"
24 | Timestamp_Nanos_field_name protoreflect.Name = "nanos"
25 |
26 | Timestamp_Seconds_field_fullname protoreflect.FullName = "google.protobuf.Timestamp.seconds"
27 | Timestamp_Nanos_field_fullname protoreflect.FullName = "google.protobuf.Timestamp.nanos"
28 | )
29 |
30 | // Field numbers for google.protobuf.Timestamp.
31 | const (
32 | Timestamp_Seconds_field_number protoreflect.FieldNumber = 1
33 | Timestamp_Nanos_field_number protoreflect.FieldNumber = 2
34 | )
35 |
--------------------------------------------------------------------------------
/tools/tentool/stats/parse.go:
--------------------------------------------------------------------------------
1 | package stats
2 |
3 | import (
4 | "fmt"
5 | "regexp"
6 | "sort"
7 | "strings"
8 |
9 | yaml "gopkg.in/yaml.v2"
10 | )
11 |
12 | var reg = regexp.MustCompile(``)
13 |
14 | // ParseMain parses tenhou main page http://tenhou.net/sc/raw/
15 | // and returns list of year index archives. Like scraw2017.zip
16 | func ParseMain(data string) []string {
17 | sub := reg.FindAllStringSubmatch(data, -1)
18 | res := make([]string, len(sub))
19 | for k, v := range sub {
20 | res[k] = v[1]
21 | }
22 | sort.Strings(res)
23 | return res
24 | }
25 |
26 | type ListItem struct {
27 | File string `yaml:"file"`
28 | Size int `yaml:"size"`
29 | }
30 |
31 | func MustParseList(data string) []ListItem {
32 | out, err := ParseList(data)
33 | if err != nil {
34 | panic(err)
35 | }
36 | return out
37 | }
38 |
39 | func ParseList(data string) ([]ListItem, error) {
40 | var out []ListItem
41 | first := strings.Index(data, "[")
42 | last := strings.LastIndex(data, "]")
43 | if first == -1 || last == -1 {
44 | return nil, fmt.Errorf("Incorrect string")
45 | }
46 | data = data[first : last+1]
47 | data = strings.Replace(data, ":", ": ", -1)
48 | err := yaml.Unmarshal([]byte(data), &out)
49 | if err != nil {
50 | return nil, err
51 | }
52 | return out, nil
53 | }
54 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/yaku/rules_predefined.go:
--------------------------------------------------------------------------------
1 | package yaku
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/tile"
5 | )
6 |
7 | func RulesEMA() *RulesStruct {
8 | return &RulesStruct{
9 | IsOpenTanyao: true,
10 | IsHaiteiFromLiveOnly: true,
11 | RenhouLimit: LimitMangan,
12 | IsIpatsu: true,
13 | IsUra: true,
14 | IsGreenRequired: false,
15 | IsRinshanFu: true,
16 | }
17 | }
18 |
19 | func RulesJPMPLA() *RulesStruct {
20 | return &RulesStruct{
21 | IsOpenTanyao: true,
22 | IsHaiteiFromLiveOnly: true,
23 | RenhouLimit: LimitMangan,
24 | IsIpatsu: false,
25 | IsUra: false,
26 | IsGreenRequired: true,
27 | IsRinshanFu: false,
28 | }
29 | }
30 |
31 | func RulesJPMPLB() *RulesStruct {
32 | return RulesEMA()
33 | }
34 |
35 | func RulesTenhouRed() *RulesStruct {
36 | return &RulesStruct{
37 | IsOpenTanyao: true,
38 | IsHaiteiFromLiveOnly: true,
39 | RenhouLimit: LimitNone,
40 | AkaDoras: []tile.Instance{
41 | tile.Man5.Instance(0),
42 | tile.Pin5.Instance(0),
43 | tile.Sou5.Instance(0),
44 | },
45 | IsIpatsu: true,
46 | IsUra: true,
47 | IsGreenRequired: false,
48 | IsRinshanFu: true,
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe_opaque.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package impl
6 |
7 | import (
8 | "sync/atomic"
9 | "unsafe"
10 | )
11 |
12 | func (p pointer) AtomicGetPointer() pointer {
13 | return pointer{p: atomic.LoadPointer((*unsafe.Pointer)(p.p))}
14 | }
15 |
16 | func (p pointer) AtomicSetPointer(v pointer) {
17 | atomic.StorePointer((*unsafe.Pointer)(p.p), v.p)
18 | }
19 |
20 | func (p pointer) AtomicSetNilPointer() {
21 | atomic.StorePointer((*unsafe.Pointer)(p.p), unsafe.Pointer(nil))
22 | }
23 |
24 | func (p pointer) AtomicSetPointerIfNil(v pointer) pointer {
25 | if atomic.CompareAndSwapPointer((*unsafe.Pointer)(p.p), unsafe.Pointer(nil), v.p) {
26 | return v
27 | }
28 | return pointer{p: atomic.LoadPointer((*unsafe.Pointer)(p.p))}
29 | }
30 |
31 | type atomicV1MessageInfo struct{ p Pointer }
32 |
33 | func (mi *atomicV1MessageInfo) Get() Pointer {
34 | return Pointer(atomic.LoadPointer((*unsafe.Pointer)(&mi.p)))
35 | }
36 |
37 | func (mi *atomicV1MessageInfo) SetIfNil(p Pointer) Pointer {
38 | if atomic.CompareAndSwapPointer((*unsafe.Pointer)(&mi.p), nil, unsafe.Pointer(p)) {
39 | return p
40 | }
41 | return mi.Get()
42 | }
43 |
--------------------------------------------------------------------------------
/tools/tentool/logs/parse_test.go:
--------------------------------------------------------------------------------
1 | package logs
2 |
3 | import (
4 | "io/ioutil"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/assert"
8 | "github.com/stretchr/testify/require"
9 | )
10 |
11 | func TestParseIDs(t *testing.T) {
12 | assert.Equal(t, []string{
13 | "2018092823gm-00a9-0000-2735720b",
14 | "2018092823gm-00a9-0000-3e233540",
15 | "2018092823gm-00a9-0000-445a08e4",
16 | "2018092823gm-00a9-0000-5fc2633e",
17 | "2018092823gm-00a9-0000-64b7a22b",
18 | "2018092823gm-00a9-0000-9b1b0e33",
19 | "2018092823gm-00a9-0000-c10a110c",
20 | "2018092823gm-00b9-0000-a2899a33",
21 | "2018092823gm-00b9-0000-c5512392",
22 | "2018092823gm-00e1-0000-af14e5c0"}, ParseIDs(loadTestData(t, "scc.html")))
23 | }
24 |
25 | func TestParseIDs2(t *testing.T) {
26 | assert.Equal(t, []string{
27 | "2018052202gm-0029-0000-4d37104e",
28 | "2018052202gm-0029-0000-5337edec",
29 | "2018052203gm-0029-0000-e57c0825",
30 | }, ParseIDs(`
31 | http://tenhou.net/0/?log=2018052202gm-0029-0000-5337edec&tw=0
32 | http://tenhou.net/0/?log=2018052202gm-0029-0000-4d37104e&tw=2
33 | http://tenhou.net/0/?log=2018052203gm-0029-0000-e57c0825&tw=0
34 | `))
35 | }
36 |
37 | func loadTestData(t require.TestingT, filename string) string {
38 | data, err := ioutil.ReadFile("test_data/" + filename)
39 | require.NoError(t, err)
40 | return string(data)
41 | }
42 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/descopts/options.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package descopts contains the nil pointers to concrete descriptor options.
6 | //
7 | // This package exists as a form of reverse dependency injection so that certain
8 | // packages (e.g., internal/filedesc and internal/filetype can avoid a direct
9 | // dependency on the descriptor proto package).
10 | package descopts
11 |
12 | import "google.golang.org/protobuf/reflect/protoreflect"
13 |
14 | // These variables are set by the init function in descriptor.pb.go via logic
15 | // in internal/filetype. In other words, so long as the descriptor proto package
16 | // is linked in, these variables will be populated.
17 | //
18 | // Each variable is populated with a nil pointer to the options struct.
19 | var (
20 | File protoreflect.ProtoMessage
21 | Enum protoreflect.ProtoMessage
22 | EnumValue protoreflect.ProtoMessage
23 | Message protoreflect.ProtoMessage
24 | Field protoreflect.ProtoMessage
25 | Oneof protoreflect.ProtoMessage
26 | ExtensionRange protoreflect.ProtoMessage
27 | Service protoreflect.ProtoMessage
28 | Method protoreflect.ProtoMessage
29 | )
30 |
--------------------------------------------------------------------------------
/vendor/github.com/inconshreveable/mousetrap/trap_windows.go:
--------------------------------------------------------------------------------
1 | package mousetrap
2 |
3 | import (
4 | "syscall"
5 | "unsafe"
6 | )
7 |
8 | func getProcessEntry(pid int) (*syscall.ProcessEntry32, error) {
9 | snapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)
10 | if err != nil {
11 | return nil, err
12 | }
13 | defer syscall.CloseHandle(snapshot)
14 | var procEntry syscall.ProcessEntry32
15 | procEntry.Size = uint32(unsafe.Sizeof(procEntry))
16 | if err = syscall.Process32First(snapshot, &procEntry); err != nil {
17 | return nil, err
18 | }
19 | for {
20 | if procEntry.ProcessID == uint32(pid) {
21 | return &procEntry, nil
22 | }
23 | err = syscall.Process32Next(snapshot, &procEntry)
24 | if err != nil {
25 | return nil, err
26 | }
27 | }
28 | }
29 |
30 | // StartedByExplorer returns true if the program was invoked by the user double-clicking
31 | // on the executable from explorer.exe
32 | //
33 | // It is conservative and returns false if any of the internal calls fail.
34 | // It does not guarantee that the program was run from a terminal. It only can tell you
35 | // whether it was launched from explorer.exe
36 | func StartedByExplorer() bool {
37 | pe, err := getProcessEntry(syscall.Getppid())
38 | if err != nil {
39 | return false
40 | }
41 | return "explorer.exe" == syscall.UTF16ToString(pe.ExeFile[:])
42 | }
43 |
--------------------------------------------------------------------------------
/tbase/meld.go:
--------------------------------------------------------------------------------
1 | package tbase
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/tile"
5 | )
6 |
7 | type Meld int
8 | type Melds []Meld
9 | type MeldKan Meld
10 | type MeldPon Meld
11 | type MeldChi Meld
12 |
13 | type MeldType int
14 |
15 | const (
16 | MeldTypeBad MeldType = iota
17 | MeldTypeChi
18 | MeldTypePon
19 | MeldTypeKan
20 | )
21 |
22 | func (m Meld) Extract(first, last int) int {
23 | shift := uint(16 - last)
24 | mask := 0
25 | for k := first; k < last; k++ {
26 | mask = mask*2 + 1
27 | }
28 | val := int(m>>shift) & mask
29 | return val
30 | }
31 |
32 | func (m Meld) Decode() *Called {
33 | return DecodeCalled(m)
34 | }
35 |
36 | func (m Melds) Decode() CalledList {
37 | x := make(CalledList, len(m))
38 | for k, v := range m {
39 | x[k] = v.Decode()
40 | }
41 | return x
42 | }
43 |
44 | func (m Meld) Type() MeldType {
45 | if m.Extract(13, 14) == 1 {
46 | return MeldTypeChi
47 | }
48 | if m.Extract(8, 13) == 0 {
49 | return MeldTypeKan
50 | }
51 | return MeldTypePon
52 | }
53 |
54 | func (m Meld) Who() Opponent {
55 | return Opponent(m.Extract(14, 16))
56 | }
57 |
58 | func (m Meld) Instance(f, l int) tile.Instance {
59 | return tile.Instance(m.Extract(f, l))
60 | }
61 |
62 | func getBase(base int) tile.Instance {
63 | t := tile.Tile(base/4) + tile.TileBegin
64 | copyId := tile.CopyID(base % 4)
65 | return t.Instance(copyId)
66 | }
67 |
--------------------------------------------------------------------------------
/tools/tentool/utils/file.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "io"
5 | "os"
6 | "path/filepath"
7 | )
8 |
9 | func MakeDirForFile(filename string) error {
10 | dir := filepath.Dir(filename)
11 | return os.MkdirAll(dir, os.ModePerm)
12 | }
13 |
14 | type FileWriter struct {
15 | path string
16 | tmpPath string
17 | file *os.File
18 | }
19 |
20 | var _ io.Writer = &FileWriter{}
21 |
22 | func CreateFile(name string) (*FileWriter, error) {
23 | err := MakeDirForFile(name)
24 | if err != nil {
25 | return nil, err
26 | }
27 | w := &FileWriter{
28 | path: name,
29 | tmpPath: name + ".tmp",
30 | }
31 | w.file, err = os.Create(w.tmpPath)
32 | if err != nil {
33 | return nil, err
34 | }
35 | return w, nil
36 | }
37 |
38 | func (w *FileWriter) Write(data []byte) (int, error) {
39 | return w.file.Write(data)
40 | }
41 |
42 | func (w *FileWriter) CommitOnSuccess(err *error) {
43 | w.Close()
44 | if *err != nil {
45 | return
46 | }
47 | *err = w.Commit()
48 | }
49 |
50 | func (w *FileWriter) Commit() error {
51 | return os.Rename(w.tmpPath, w.path)
52 | }
53 |
54 | func (w *FileWriter) Close() error {
55 | return w.file.Close()
56 | }
57 |
58 | func FileExists(path string) (bool, error) {
59 | _, err := os.Stat(path)
60 | if err == nil {
61 | return true, nil
62 | }
63 | if os.IsNotExist(err) {
64 | return false, nil
65 | }
66 | return false, err
67 | }
68 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/PATENTS:
--------------------------------------------------------------------------------
1 | Additional IP Rights Grant (Patents)
2 |
3 | "This implementation" means the copyrightable works distributed by
4 | Google as part of the Go project.
5 |
6 | Google hereby grants to You a perpetual, worldwide, non-exclusive,
7 | no-charge, royalty-free, irrevocable (except as stated in this section)
8 | patent license to make, have made, use, offer to sell, sell, import,
9 | transfer and otherwise run, modify and propagate the contents of this
10 | implementation of Go, where such license applies only to those patent
11 | claims, both currently owned or controlled by Google and acquired in
12 | the future, licensable by Google that are necessarily infringed by this
13 | implementation of Go. This grant does not include claims that would be
14 | infringed only as a consequence of further modification of this
15 | implementation. If you or your agent or exclusive licensee institute or
16 | order or agree to the institution of patent litigation against any
17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging
18 | that this implementation of Go or any code incorporated within this
19 | implementation of Go constitutes direct or contributory patent
20 | infringement, or inducement of patent infringement, then any patent
21 | rights granted to you under this License for this implementation of Go
22 | shall terminate as of the date such litigation is filed.
23 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/hand/effective/sort.go:
--------------------------------------------------------------------------------
1 | package effective
2 |
3 | import "github.com/dnovikoff/tempai-core/tile"
4 |
5 | type sSortId uint32
6 |
7 | func newSortId(uCount, tCount, value int) sSortId {
8 | val := (13 - sSortId(value))
9 | val = (val << 8) | sSortId(uCount)
10 | val = (val << 8) | sSortId(tCount)
11 |
12 | return val
13 | }
14 |
15 | func (id sSortId) betterThan(other sSortId) bool {
16 | return id > other
17 | }
18 |
19 | type ResultsSorted []*Result
20 |
21 | func (r ResultsSorted) Best() *Result {
22 | if len(r) == 0 {
23 | return nil
24 | }
25 | return r[0]
26 | }
27 |
28 | func (r ResultsSorted) Len() int {
29 | return len(r)
30 | }
31 |
32 | func (r ResultsSorted) Swap(i, j int) {
33 | r[i], r[j] = r[j], r[i]
34 | }
35 |
36 | func tileSortId(t tile.Tile) int {
37 | return (tilePriority(t) << 8) | int(t)
38 | }
39 |
40 | func tileLess(l, r tile.Tile) bool {
41 | return tileSortId(l) < tileSortId(r)
42 | }
43 |
44 | func effLess(l, r *Result) bool {
45 | lhs, rhs := l.sortId, r.sortId
46 | if lhs.betterThan(rhs) {
47 | return true
48 | } else if rhs.betterThan(lhs) {
49 | return false
50 | }
51 | return tileLess(l.Tile, r.Tile)
52 | }
53 |
54 | func (r ResultsSorted) Less(i, j int) bool {
55 | return effLess(r[i], r[j])
56 | }
57 |
58 | func (r ResultsSorted) First() *Result {
59 | if len(r) == 0 {
60 | return nil
61 | }
62 | return r[0]
63 | }
64 |
--------------------------------------------------------------------------------
/vendor/gopkg.in/yaml.v2/LICENSE.libyaml:
--------------------------------------------------------------------------------
1 | The following files were ported to Go from C files of libyaml, and thus
2 | are still covered by their original copyright and license:
3 |
4 | apic.go
5 | emitterc.go
6 | parserc.go
7 | readerc.go
8 | scannerc.go
9 | writerc.go
10 | yamlh.go
11 | yamlprivateh.go
12 |
13 | Copyright (c) 2006 Kirill Simonov
14 |
15 | Permission is hereby granted, free of charge, to any person obtaining a copy of
16 | this software and associated documentation files (the "Software"), to deal in
17 | the Software without restriction, including without limitation the rights to
18 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
19 | of the Software, and to permit persons to whom the Software is furnished to do
20 | so, subject to the following conditions:
21 |
22 | The above copyright notice and this permission notice shall be included in all
23 | copies or substantial portions of the Software.
24 |
25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 | SOFTWARE.
32 |
--------------------------------------------------------------------------------
/log/info_test.go:
--------------------------------------------------------------------------------
1 | package log
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | "github.com/stretchr/testify/require"
8 | )
9 |
10 | func TestLobbyDecode(t *testing.T) {
11 | decode := func(in string) string {
12 | res, err := DecodeLobby(in)
13 | require.NoError(t, err)
14 | return res.DebugString()
15 | }
16 | assert.Equal(t, "AKT4fX", decode("00a1"))
17 | assert.Equal(t, "AKH4fX", decode("00a9"))
18 | assert.Equal(t, "AKT4F0", decode("0841"))
19 | }
20 |
21 | func TestInfoParse(t *testing.T) {
22 | parse := func(in string) string {
23 | ret, err := ParseLogInfo(in)
24 | require.NoError(t, err)
25 | return ret.DebugString()
26 | }
27 |
28 | assert.Equal(t, "[2009-06-18 06:00:00 +0000 UTC][AKT4fX][0][6d13c207]", parse("2009061806gm-00a1-0000-6d13c207"))
29 | assert.Equal(t, "[2009-03-17 02:00:00 +0000 UTC][AKT4fX][0][336ee82a]", parse("00a1/2009/03/17/2009031702gm-00a1-0000-336ee82a.mjlog"))
30 | assert.Equal(t, "[2009-09-15 15:00:00 +0000 UTC][AKH4fX][0][1753da1d]", parse("http://tenhou.net/0/?log=2009091515gm-00a9-0000-1753da1d"))
31 | }
32 |
33 | func TestInfoParsefilename(t *testing.T) {
34 | ret, err := ParseLogInfo("http://tenhou.net/0/?log=2017022002gm-000b-2873-xc0294a92421e&tw=3")
35 | require.NoError(t, err)
36 | assert.Equal(t, "http://tenhou.net/0/?log=2017022002gm-000b-2873-xc0294a92421e", ret.LogUrl)
37 | assert.Equal(t, "https://tenhou.net/0/log/?2017022002gm-000b-2873-fb28df66", ret.XmlUrl)
38 | }
39 |
--------------------------------------------------------------------------------
/util/util_test/xml_test.go:
--------------------------------------------------------------------------------
1 | package util_test
2 |
3 | import (
4 | "testing"
5 |
6 | "github.com/stretchr/testify/assert"
7 | "github.com/stretchr/testify/require"
8 |
9 | "github.com/dnovikoff/tenhou/parser"
10 | )
11 |
12 | func TestParseXML(t *testing.T) {
13 | ret, err := parser.ParseXML(``)
14 | require.NoError(t, err)
15 | require.Equal(t, 1, len(ret))
16 | assert.Equal(t, parser.Node{
17 | Name: "N",
18 | Attributes: map[string]string{
19 | "type": "1",
20 | "hai0": "132",
21 | "hai1": "134",
22 | },
23 | }, ret[0])
24 | }
25 |
26 | func TestParseXMLList(t *testing.T) {
27 | ret, err := parser.ParseXML(``)
28 | require.NoError(t, err)
29 | assert.Equal(t, parser.Nodes{
30 | parser.Node{Name: "A"},
31 | parser.Node{Name: "B"},
32 | }, ret)
33 | }
34 |
35 | func TestParseXMLStrictCheck(t *testing.T) {
36 | ret, err := parser.ParseXML(``)
37 | require.NoError(t, err)
38 | require.Equal(t, 1, len(ret))
39 | assert.Equal(t, parser.Node{
40 | Name: "HELO",
41 | Attributes: map[string]string{
42 | "ratingscale": "PF3=1.000000&PF4=1.000000&PF01C=0.582222&PF02C=0.501632&PF03C=0.414869&PF11C=0.823386&PF12C=0.709416&PF13C=0.586714&PF23C=0.378722&PF33C=0.535594&PF1C00=8.000000",
43 | },
44 | }, ret[0])
45 | }
46 |
--------------------------------------------------------------------------------
/tools/tentool/utils/interactive_tracker.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "os"
5 |
6 | "github.com/c2h5oh/datasize"
7 | )
8 |
9 | type InteractiveTracker struct {
10 | u, p string
11 | total int64
12 | progress int64
13 | interactive bool
14 | w *InteractiveWriter
15 | }
16 |
17 | func NewInteractiveTracker(u, p string, i bool) *InteractiveTracker {
18 | return &InteractiveTracker{u: u, p: p, interactive: i, w: NewInteractiveWriter(os.Stdout)}
19 | }
20 |
21 | func (t *InteractiveTracker) SetPath(p string) {
22 | t.p = p
23 | }
24 |
25 | func (t *InteractiveTracker) Start(total int64) {
26 | t.total = total
27 | t.writeHeader()
28 | }
29 |
30 | func (t *InteractiveTracker) writeHeader() {
31 | if t.p == "" {
32 | t.w.Printf("Downloading %v", t.u)
33 | } else {
34 | t.w.Printf("Downloading %v to %v", t.u, t.p)
35 | }
36 | t.w.Println()
37 | }
38 |
39 | func (t *InteractiveTracker) Write(bytes int) {
40 | if !t.interactive {
41 | return
42 | }
43 | t.progress += int64(bytes)
44 | if t.total == 0 {
45 | t.w.Printf("%v of unknown total size", datasize.ByteSize(t.progress))
46 | } else {
47 | t.w.Printf("%s/%s (%v%%)",
48 | datasize.ByteSize(t.progress).HumanReadable(),
49 | datasize.ByteSize(t.total).HumanReadable(),
50 | t.progress*100/t.total,
51 | )
52 | }
53 | }
54 |
55 | func (t *InteractiveTracker) Done(total int64, err error) {
56 | if !t.interactive {
57 | return
58 | }
59 | t.w.Println()
60 | }
61 |
--------------------------------------------------------------------------------
/tools/tentool/stats/test_data/scb.log:
--------------------------------------------------------------------------------
1 | 00:00 | 17 | 三般南喰赤- | petshop(+56.0) NoName(+1.0) 役満役満(-57.0)
2 | 00:00 | 12 | 三特南喰赤- | とらぽ(+56.0) クガツハズカム(-16.0) 古墳(-40.0)
3 | 00:00 | 25 | 四般南喰赤- | m9(-Д-)(+52.0) insigne(+6.0) Rocks12(-24.0) ちっつー(-34.0)
4 | 00:00 | 31 | 四上南喰赤- | beside(+46.0) CAT777(+8.0) 758dagay(-15.0) silveraq(-39.0)
5 | 00:00 | 19 | 三般南喰赤- | シャボーズ(+41.0) 090(-7.0) NoName(-34.0)
6 | 00:00 | 06 | 四上東喰赤- | シエスタ410(+46.0) taiwanco(+3.0) expressJ(-18.0) 佳太郎(-31.0)
7 | 00:00 | 38 | 四特南喰赤- | 荒巻すかる(+51.0) Pin(+8.0) 牢人(-21.0) 名脇役(-38.0)
8 | 00:00 | 33 | 四般南喰赤- | sphinx*(+43.0) NoName(+8.0) kazkum(-17.0) lassi(-34.0)
9 | 00:00 | 08 | 三般南喰赤- | か・す共が(+80.0) Akkari~n(-17.0) NoName(-63.0)
10 | 00:00 | 11 | 三上東喰赤- | deku(+78.0) みらい☆彡(-2.0) akibo528(-76.0)
11 | 00:00 | 05 | 三般東喰赤- | 龍真(+47.0) りんご1529(-8.0) NoName(-39.0)
12 | 00:00 | 16 | 四般東喰赤- | NoName(+43.0) iatw(+7.0) faweff(-18.0) supa-ku(-32.0)
13 | 00:00 | 12 | 四上東喰赤- | どかーん(+65.0) マイヤー(+9.0) hhmmhh(-29.0) lsrlzy(-45.0)
14 | 00:00 | 31 | 四上南喰赤- | らじこ(+42.0) アイガッチャ(+8.0) rt224689(-16.0) lz73(-34.0)
15 | 00:00 | 12 | 四般東--- | 蛍のケイぼん(+55.0) snowmous(+13.0) NoName(-23.0) shirou55(-45.0)
16 | 00:00 | 11 | 四特東喰赤- | 石戸明星(+53.0) ブルーカミカゼ(+9.0) birdman(-15.0) 鮫島(-47.0)
17 | 00:00 | 13 | 三上南喰赤- | バクシン(+80.0) 今日もだめだった(-8.0) p7(-72.0)
18 | 00:00 | 27 | 四般南喰赤- | ほめ777(+49.0) ZaneTrue(+10.0) とよすけ31(-13.0) あぐー(-46.0)
19 | 00:00 | 22 | 四特南喰赤- | 炎炎炎(+47.0) よしぞー(+4.0) Saki-san(-20.0) ふがいないや(-31.0)
20 | 00:00 | 03 | 三般東喰赤- | らおさん(+38.0) Overmind(-9.0) しょうゆん!(-29.0)
21 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/set/ints.go:
--------------------------------------------------------------------------------
1 | // Copyright 2018 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package set provides simple set data structures for uint64s.
6 | package set
7 |
8 | import "math/bits"
9 |
10 | // int64s represents a set of integers within the range of 0..63.
11 | type int64s uint64
12 |
13 | func (bs *int64s) Len() int {
14 | return bits.OnesCount64(uint64(*bs))
15 | }
16 | func (bs *int64s) Has(n uint64) bool {
17 | return uint64(*bs)&(uint64(1)< 0
18 | }
19 | func (bs *int64s) Set(n uint64) {
20 | *(*uint64)(bs) |= uint64(1) << n
21 | }
22 | func (bs *int64s) Clear(n uint64) {
23 | *(*uint64)(bs) &^= uint64(1) << n
24 | }
25 |
26 | // Ints represents a set of integers within the range of 0..math.MaxUint64.
27 | type Ints struct {
28 | lo int64s
29 | hi map[uint64]struct{}
30 | }
31 |
32 | func (bs *Ints) Len() int {
33 | return bs.lo.Len() + len(bs.hi)
34 | }
35 | func (bs *Ints) Has(n uint64) bool {
36 | if n < 64 {
37 | return bs.lo.Has(n)
38 | }
39 | _, ok := bs.hi[n]
40 | return ok
41 | }
42 | func (bs *Ints) Set(n uint64) {
43 | if n < 64 {
44 | bs.lo.Set(n)
45 | return
46 | }
47 | if bs.hi == nil {
48 | bs.hi = make(map[uint64]struct{})
49 | }
50 | bs.hi[n] = struct{}{}
51 | }
52 | func (bs *Ints) Clear(n uint64) {
53 | if n < 64 {
54 | bs.lo.Clear(n)
55 | return
56 | }
57 | delete(bs.hi, n)
58 | }
59 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/compact/generator.go:
--------------------------------------------------------------------------------
1 | package compact
2 |
3 | import (
4 | "errors"
5 |
6 | "github.com/dnovikoff/tempai-core/tile"
7 | )
8 |
9 | type Generator struct {
10 | instances Instances
11 | }
12 |
13 | func NewTileGenerator() *Generator {
14 | return &Generator{AllInstances()}
15 | }
16 |
17 | func (g *Generator) TilesLeft() tile.Instances {
18 | return g.instances.Instances()
19 | }
20 |
21 | func (g *Generator) Instance(t tile.Tile) tile.Instance {
22 | m := g.instances.GetMask(t)
23 | if m.IsEmpty() {
24 | return tile.InstanceNull
25 | }
26 | ret := m.First()
27 | g.instances.Remove(ret)
28 | return ret
29 | }
30 |
31 | func (g *Generator) CompactFromString(str string) (Instances, error) {
32 | tiles, err := g.InstancesFromString(str)
33 | if err != nil {
34 | return nil, err
35 | }
36 | return NewInstances().Add(tiles), nil
37 | }
38 |
39 | func (g *Generator) InstancesFromString(str string) (tile.Instances, error) {
40 | tiles, err := tile.NewTilesFromString(str)
41 | if err != nil {
42 | return nil, err
43 | }
44 | ret := g.Tiles(tiles)
45 | if ret == nil {
46 | return nil, errors.New("Incorrect input string")
47 | }
48 | return ret, nil
49 | }
50 |
51 | func (g *Generator) Tiles(tiles tile.Tiles) tile.Instances {
52 | ret := make(tile.Instances, len(tiles))
53 | for i, t := range tiles {
54 | r := g.Instance(t)
55 | if r == tile.InstanceNull {
56 | return nil
57 | }
58 | ret[i] = r
59 | }
60 | return ret
61 | }
62 |
--------------------------------------------------------------------------------
/client/controller.go:
--------------------------------------------------------------------------------
1 | package client
2 |
3 | import (
4 | "github.com/dnovikoff/tenhou/tbase"
5 | )
6 |
7 | type Suggest int
8 |
9 | const (
10 | SuggestNone Suggest = 0
11 | )
12 |
13 | const (
14 | SuggestKan Suggest = 1 << iota
15 | SuggestPon // 2
16 | SuggestChi // 4
17 | SuggestRon // 8
18 | SuggestTsumo // 16
19 | SuggestRiichi // 32
20 | SuggestDraw // 64
21 | SuggetSanmaDora // 128
22 | )
23 |
24 | func (s Suggest) Check(x Suggest) bool {
25 | return (s & x) == x
26 | }
27 |
28 | type UNController interface {
29 | UserList(UserList)
30 | Reconnect(Reconnect)
31 | }
32 |
33 | // This is how client looks from server's point of view
34 | type Controller interface {
35 | UNController
36 |
37 | Drop(Drop)
38 | Take(Take)
39 | Reach(Reach)
40 | Declare(Declare)
41 | Init(Init)
42 | Reinit(Reinit)
43 | LogInfo(LogInfo)
44 | Go(Go)
45 | Hello(Hello)
46 |
47 | // TODO: research
48 | LobbyStats(LobbyStats)
49 | Agari(tbase.Agari)
50 | Indicator(WithInstance)
51 | // TODO: research add
52 | EndButton(EndButton)
53 | Furiten(Furiten)
54 | Ryuukyoku(tbase.Ryuukyoku)
55 | Rejoin(Rejoin)
56 | Disconnect(WithOpponent)
57 | Chat(Chat)
58 | // TODO: research
59 | Ranking(Ranking)
60 | Recover(Recover)
61 | }
62 |
63 | const DefaultRatingScale = "PF3=1.000000&PF4=1.000000&PF01C=0.582222&PF02C=0.501632&PF03C=0.414869&PF11C=0.823386&PF12C=0.709416&PF13C=0.586714&PF23C=0.378722&PF33C=0.535594&PF1C00=8.000000"
64 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/hand/calc/options.go:
--------------------------------------------------------------------------------
1 | package calc
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/compact"
5 | )
6 |
7 | type Form int
8 |
9 | const (
10 | Regular Form = 1 << iota
11 | Pairs
12 | Kokushi
13 | )
14 |
15 | func (f Form) Check(x Form) bool {
16 | return (f & x) == x
17 | }
18 |
19 | type Options struct {
20 | Opened int
21 | Used compact.Instances
22 | Results Results
23 | Declared Melds
24 | Forms Form
25 |
26 | StartMelds Melds
27 | }
28 |
29 | type Option func(*Options)
30 |
31 | func GetOptions(opts ...Option) *Options {
32 | r := Options{
33 | Forms: Kokushi | Pairs | Regular,
34 | }
35 | for _, opt := range opts {
36 | opt(&r)
37 | }
38 | return &r
39 | }
40 |
41 | func Opened(x int) Option {
42 | return func(c *Options) {
43 | c.Opened = x
44 | }
45 | }
46 |
47 | func Used(x compact.Instances) Option {
48 | return func(c *Options) {
49 | if c.Used == nil {
50 | c.Used = x
51 | } else {
52 | c.Used = c.Used.Merge(x)
53 | }
54 | }
55 | }
56 |
57 | func SetResults(x Results) Option {
58 | return func(c *Options) {
59 | c.Results = x
60 | }
61 | }
62 |
63 | func Declared(melds Melds) Option {
64 | opened := len(melds)
65 | return func(c *Options) {
66 | c.Declared = melds
67 | c.Opened += opened
68 | }
69 | }
70 |
71 | func Forms(x Form) Option {
72 | return func(c *Options) {
73 | c.Forms = x
74 | }
75 | }
76 |
77 | func StartMelds(m Melds) Option {
78 | return func(c *Options) {
79 | c.StartMelds = m
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/tools/tentool/stats/test_data/scd.log:
--------------------------------------------------------------------------------
1 | 00:02 | 08 | 三若東喰赤祝5 | cruyff(+70.0,+5枚) akahiro(-20.0,-3枚) qzc(-50.0,-2枚)
2 | 00:05 | 09 | 三若東喰赤祝5 | ブルース・リー(+55.0,+2枚) HUNTER(-5.0,-1枚) NoName(-50.0,-1枚)
3 | 00:10 | 02 | 三若東喰赤祝5 | rassunn(+76.0,+4枚) qzc(-5.0,0枚) 福音(-71.0,-4枚)
4 | 00:13 | 06 | 三若東喰赤祝5 | rassunn(+69.0,+2枚) cruyff(-7.0,0枚) ケスラー(-62.0,-2枚)
5 | 00:15 | 05 | 三若東喰赤祝5 | qzc(+51.0,+2枚) HUNTER(-9.0,-1枚) ブルース・リー(-42.0,-1枚)
6 | 00:20 | 05 | 三若東喰赤祝5 | NoName(+65.0,0枚) ケスラー(+7.0,+1枚) cruyff(-72.0,-1枚)
7 | 00:21 | 05 | 三若東喰赤祝5 | qzc(+46.0,-1枚) HUNTER(-5.0,+1枚) asd(-41.0,0枚)
8 | 00:26 | 04 | 三若東喰赤祝5 | ケスラー(+60.0,+1枚) ロトの刀(-3.0,+2枚) asd(-57.0,-3枚)
9 | 00:26 | 05 | 三若東喰赤祝5 | シロウー(+58.0,+13枚) cruyff(+3.0,-4枚) qzc(-61.0,-9枚)
10 | 00:31 | 06 | 三若東喰赤祝5 | ロトの刀(+68.0,+10枚) ケスラー(-16.0,-6枚) No--Name(-52.0,-4枚)
11 | 00:32 | 13 | 三若東喰赤祝5 | cruyff(+82.0,+3枚) シロウー(-4.0,0枚) asd(-78.0,-3枚)
12 | 00:46 | 03 | 三若東喰赤祝5 | ケスラー(+54.0,0枚) ユーダイクス(-3.0,0枚) NoName(-51.0,0枚)
13 | 00:52 | 08 | 三若東喰赤祝5 | ケスラー(+61.0,+4枚) akahiro(-11.0,-3枚) ユーダイクス(-50.0,-1枚)
14 | 00:52 | 04 | 三若東喰赤祝5 | simapuro(+51.0,0枚) itoyan(-4.0,0枚) NoName(-47.0,0枚)
15 | 01:01 | 10 | 三若東喰赤祝5 | ケスラー(+64.0,+1枚) fu-ka(+4.0,+2枚) ユーダイクス(-68.0,-3枚)
16 | 02:35 | 04 | 三若東喰赤祝5 | ロトの刀(+50.0,-1枚) 訓練生ユウ(-6.0,0枚) Ikkey(-44.0,+1枚)
17 | 10:57 | 07 | 三若東喰赤祝5 | 訓練生ユウ(+60.0,+7枚) 藤枝(-9.0,-3枚) ラザニア21(-51.0,-4枚)
18 | 11:06 | 08 | 三若東喰赤祝5 | 藤枝(+91.0,+8枚) 訓練生ユウ(-23.0,-3枚) すべては牌操作(-68.0,-5枚)
19 | 11:15 | 07 | 三若東喰赤祝5 | corius(+93.0,+4枚) モノのじ(-21.0,-2枚) 藤枝(-72.0,-2枚)
20 | 11:22 | 06 | 三若東喰赤祝5 | 藤枝(+50.0,0枚) モノのじ(-9.0,-1枚) 訓練生ユウ(-41.0,+1枚)
21 |
--------------------------------------------------------------------------------
/tbase/meld_test.go:
--------------------------------------------------------------------------------
1 | package tbase
2 |
3 | import (
4 | "strconv"
5 | "testing"
6 |
7 | "github.com/stretchr/testify/assert"
8 |
9 | "github.com/dnovikoff/tempai-core/tile"
10 | )
11 |
12 | func TestMeldsBase(t *testing.T) {
13 | for _, v := range []struct {
14 | expected tile.Tile
15 | m Meld
16 | }{
17 | {tile.North, 46633},
18 | {tile.White, 47690},
19 | {tile.Green, 49705},
20 | } {
21 | t.Run(v.expected.String()+strconv.Itoa(int(v.m)), func(t *testing.T) {
22 | assert.Equal(t, v.expected, v.m.Decode().Core.Tile())
23 | })
24 | }
25 | }
26 |
27 | func TestMelds(t *testing.T) {
28 | for _, v := range []struct {
29 | expected string
30 | m Meld
31 | }{
32 | {"444z Right", 46633},
33 | {"555z Front", 47690},
34 | {"666z Right", 49705},
35 | // Upgraded
36 | {"5555z Front", 47666},
37 | {"2222m Left", 1539},
38 | {"1111z Front", 27906},
39 | {"1111p Right", 9217},
40 | {"444s Front", 33354},
41 | } {
42 | t.Run(v.expected, func(t *testing.T) {
43 | d := v.m.Decode()
44 | actual := d.Core.Tiles().String() + " " + d.Opponent.String()
45 | assert.Equal(t, v.expected, actual)
46 | })
47 | }
48 | }
49 |
50 | func TestMeldsReconvert(t *testing.T) {
51 | for _, v := range []Meld{
52 | // chi [6]78p
53 | 37199,
54 | 33354,
55 | // Closed green kan with copyId = 1
56 | 33024,
57 | // Closed green kan with copyId = 0
58 | 32768,
59 | } {
60 | t.Run(strconv.Itoa(int(v)), func(t *testing.T) {
61 | assert.Equal(t, v, v.Decode().Encode())
62 | })
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/yaku/rules.go:
--------------------------------------------------------------------------------
1 | package yaku
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/tile"
5 | )
6 |
7 | type Rules interface {
8 | OpenTanyao() bool
9 | CheckAka(i tile.Instance) bool
10 | Renhou() Limit
11 | HaiteiFromLiveOnly() bool
12 | Ura() bool
13 | Ipatsu() bool
14 | GreenRequired() bool
15 | RinshanFu() bool
16 | }
17 |
18 | type RulesStruct struct {
19 | IsOpenTanyao bool
20 | AkaDoras []tile.Instance
21 | RenhouLimit Limit
22 | IsHaiteiFromLiveOnly bool
23 | IsUra bool
24 | IsIpatsu bool
25 | IsGreenRequired bool
26 | IsRinshanFu bool
27 | }
28 |
29 | var _ Rules = &RulesStruct{}
30 |
31 | func (r *RulesStruct) GreenRequired() bool {
32 | return r.IsGreenRequired
33 | }
34 |
35 | func (r *RulesStruct) RinshanFu() bool {
36 | return r.IsRinshanFu
37 | }
38 |
39 | func (r *RulesStruct) OpenTanyao() bool {
40 | return r.IsOpenTanyao
41 | }
42 |
43 | func (r *RulesStruct) Renhou() Limit {
44 | return r.RenhouLimit
45 | }
46 |
47 | func (r *RulesStruct) HaiteiFromLiveOnly() bool {
48 | return r.IsHaiteiFromLiveOnly
49 | }
50 |
51 | func (r *RulesStruct) Ura() bool {
52 | return r.IsUra
53 | }
54 |
55 | func (r *RulesStruct) Ipatsu() bool {
56 | return r.IsIpatsu
57 | }
58 |
59 | func (r *RulesStruct) CheckAka(i tile.Instance) bool {
60 | if len(r.AkaDoras) == 0 {
61 | return false
62 | }
63 | for _, v := range r.AkaDoras {
64 | if v == i {
65 | return true
66 | }
67 | }
68 | return false
69 | }
70 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/assert/doc.go:
--------------------------------------------------------------------------------
1 | // Package assert provides a set of comprehensive testing tools for use with the normal Go testing system.
2 | //
3 | // # Example Usage
4 | //
5 | // The following is a complete example using assert in a standard test function:
6 | //
7 | // import (
8 | // "testing"
9 | // "github.com/stretchr/testify/assert"
10 | // )
11 | //
12 | // func TestSomething(t *testing.T) {
13 | //
14 | // var a string = "Hello"
15 | // var b string = "Hello"
16 | //
17 | // assert.Equal(t, a, b, "The two words should be the same.")
18 | //
19 | // }
20 | //
21 | // if you assert many times, use the format below:
22 | //
23 | // import (
24 | // "testing"
25 | // "github.com/stretchr/testify/assert"
26 | // )
27 | //
28 | // func TestSomething(t *testing.T) {
29 | // assert := assert.New(t)
30 | //
31 | // var a string = "Hello"
32 | // var b string = "Hello"
33 | //
34 | // assert.Equal(a, b, "The two words should be the same.")
35 | // }
36 | //
37 | // # Assertions
38 | //
39 | // Assertions allow you to easily write test code, and are global funcs in the `assert` package.
40 | // All assertion functions take, as the first argument, the `*testing.T` object provided by the
41 | // testing framework. This allows the assertion funcs to write the failings and other details to
42 | // the correct place.
43 | //
44 | // Every assertion function also takes an optional string message as the final argument,
45 | // allowing custom error messages to be appended to the message the assertion method outputs.
46 | package assert
47 |
--------------------------------------------------------------------------------
/log/test_data/example.txt:
--------------------------------------------------------------------------------
1 | http://tenhou.net/0/?log=2016090816gm-0019-0000-c1eeb04f&tw=0
2 | http://e.mjv.jp/0/log/plainfiles.cgi?2016090816gm-0019-0000-c1eeb04f
3 | https://github.com/NegativeMjark/tenhou-log
4 |
5 |
6 | http://tenhou.net/0/?log=2016112620gm-0029-0000-41174e3d&tw=3
7 | http://e.mjv.jp/0/log/plainfiles.cgi?2016112620gm-0029-0000-41174e3d
8 |
9 |
10 | Тестовые данные для исправления ссылок:
11 | http://tenhou.net/0/?log=2017020203gm-000b-2873-e6b557e5&tw=0
12 | http://tenhou.net/0/?log=2017020203gm-000b-2873-x84f6522d33b4&tw=2
13 | http://tenhou.net/0/?log=2017020203gm-000b-2873-xecf8fa3f92ec&tw=3
14 | http://tenhou.net/0/?log=2017020204gm-000b-2873-a1135a18&tw=1
15 | http://tenhou.net/0/?log=2017020204gm-000b-2873-xb0418c5ccc31&tw=2
16 | http://tenhou.net/0/?log=2017020206gm-000b-2873-77e86420&tw=3
17 | http://tenhou.net/0/?log=2017020903gm-000b-2873-86bb1b01&tw=3
18 | http://tenhou.net/0/?log=2017020904gm-000b-2873-d6dd0bce&tw=2
19 | http://tenhou.net/0/?log=2017021603gm-000b-2873-x2f283b1b40bf&tw=0
20 | http://tenhou.net/0/?log=2017021604gm-000b-2873-x530c7852a15e&tw=3
21 | http://tenhou.net/0/?log=2017022002gm-000b-2873-xc0294a92421e&tw=3
22 | http://tenhou.net/0/?log=2017022003gm-000b-2873-xf96d95ed7ca6&tw=1
23 | http://tenhou.net/0/?log=2017022003gm-000b-2873-b6fe8101&tw=3
24 | http://tenhou.net/0/?log=2017022505gm-000b-17959-8f97ed43&tw=3
25 | http://tenhou.net/0/?log=2017022504gm-000b-17959-793cea5a&tw=2
26 | http://tenhou.net/0/?log=2017022503gm-000b-17959-06e70d10&tw=1
27 | http://tenhou.net/0/?log=2017022502gm-000b-17959-28dd0098&tw=0
28 |
29 |
--------------------------------------------------------------------------------
/tools/tentool/logs/test_data/scc.html:
--------------------------------------------------------------------------------
1 | 23:00 | 30 | 四鳳南喰赤- | 牌譜 | =Jam(+59.0) とびまこ(+11.0) アル中@テンパ(-14.0) mineral2(-56.0)
2 | 23:01 | 08 | 三鳳南喰赤- | 牌譜 | まじきち(+42.0) しめじん(-4.0) 湾奥アングラー(-38.0)
3 | 23:02 | 28 | 四鳳南喰赤- | 牌譜 | ドジャース(+42.0) tori0612(+9.0) ゆきさん。(-12.0)
4 | たくじろう(-39.0)
5 | 23:03 | 29 | 四鳳南喰赤- | 牌譜 | 鉄稚魚カモ養分(+54.0) sAgaさん(+14.0) 東京電力(-18.0) G.Y.M(-50.0)
6 | 23:05 | 44 | 四鳳南喰赤- | 牌譜 | ち'んぽっぽ(+41.0) 時を刻む唄(+5.0) ほーりー(-16.0)ふたば(-30.0)
7 | 23:05 | 15 | 四鳳東喰赤- | 牌譜 | kiyopin(+40.0) 六分儀ゲンドウ(+5.0) みみず(-15.0) pinpin6(-30.0)
8 | 23:08 | 31 | 四鳳南喰赤- | 牌譜 | salaman(+59.0) \(^o^)/★(+7.0) たがやす(-19.0) めんたんo(-47.0)
9 | 23:09 | 40 | 四鳳南喰赤- | 牌譜 | 嫌んなった(+74.0) 遊び心(+9.0) jijii-e(-31.0) ちょりお(-52.0)
10 | 23:09 | 14 | 三鳳南喰赤- | 牌譜 | テイラーヒル(+66.0) のーし(-12.0) 遙遠的他。(-54.0)
11 | 23:09 | 31 | 四鳳南喰赤- | 牌譜 | フツウの恋の結末(+57.0) fm44(+6.0) akaaka(-26.0) 眼
12 | 科医(-37.0)
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/yaku/yakuman_string.go:
--------------------------------------------------------------------------------
1 | // Code generated by "stringer -type=Yakuman"; DO NOT EDIT.
2 |
3 | package yaku
4 |
5 | import "strconv"
6 |
7 | func _() {
8 | // An "invalid array index" compiler error signifies that the constant values have changed.
9 | // Re-run the stringer command to generate them again.
10 | var x [1]struct{}
11 | _ = x[YakumanNone-0]
12 | _ = x[YakumanKokushi-1]
13 | _ = x[YakumanKokushi13-2]
14 | _ = x[YakumanSuukantsu-3]
15 | _ = x[YakumanSuuankou-4]
16 | _ = x[YakumanSuuankouTanki-5]
17 | _ = x[YakumanDaisangen-6]
18 | _ = x[YakumanShousuushi-7]
19 | _ = x[YakumanDaisuushi-8]
20 | _ = x[YakumanRyuuiisou-9]
21 | _ = x[YakumanTsuiisou-10]
22 | _ = x[YakumanChinrouto-11]
23 | _ = x[YakumanChuurenpooto-12]
24 | _ = x[YakumanChuurenpooto9-13]
25 | _ = x[YakumanTenhou-14]
26 | _ = x[YakumanChihou-15]
27 | _ = x[YakumanRenhou-16]
28 | }
29 |
30 | const _Yakuman_name = "YakumanNoneYakumanKokushiYakumanKokushi13YakumanSuukantsuYakumanSuuankouYakumanSuuankouTankiYakumanDaisangenYakumanShousuushiYakumanDaisuushiYakumanRyuuiisouYakumanTsuiisouYakumanChinroutoYakumanChuurenpootoYakumanChuurenpooto9YakumanTenhouYakumanChihouYakumanRenhou"
31 |
32 | var _Yakuman_index = [...]uint16{0, 11, 25, 41, 57, 72, 92, 108, 125, 141, 157, 172, 188, 207, 227, 240, 253, 266}
33 |
34 | func (i Yakuman) String() string {
35 | if i < 0 || i >= Yakuman(len(_Yakuman_index)-1) {
36 | return "Yakuman(" + strconv.FormatInt(int64(i), 10) + ")"
37 | }
38 | return _Yakuman_name[_Yakuman_index[i]:_Yakuman_index[i+1]]
39 | }
40 |
--------------------------------------------------------------------------------
/tools/tentool/utils/donwload_test.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | import (
4 | "context"
5 | "net/http"
6 | "net/http/httptest"
7 | "testing"
8 | "time"
9 |
10 | "github.com/stretchr/testify/assert"
11 | "github.com/stretchr/testify/require"
12 | )
13 |
14 | func TestDetectFilename(t *testing.T) {
15 | var handler func(w http.ResponseWriter, req *http.Request)
16 | server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
17 | handler(w, req)
18 | }))
19 | defer server.Close()
20 | c := server.Client()
21 | d := NewDownloader(Client(c))
22 | ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
23 | defer cancel()
24 | t.Run("Disposition", func(t *testing.T) {
25 | handler = func(w http.ResponseWriter, req *http.Request) {
26 | w.Header().Set("Content-Disposition", `attachment;filename="foo.png"`)
27 | w.Write([]byte(`Some content`))
28 | }
29 | filename, err := d.Filename(ctx, server.URL+"/folder/other-folder/bar.jpg")
30 | require.NoError(t, err)
31 | assert.Equal(t, "foo.png", filename)
32 | })
33 | t.Run("NoDisposition", func(t *testing.T) {
34 | var userAgent string
35 | handler = func(w http.ResponseWriter, req *http.Request) {
36 | userAgent = req.UserAgent()
37 | w.Write([]byte(`Some content`))
38 | }
39 | filename, err := d.Filename(ctx, server.URL+"/folder/other-folder/bar.jpg")
40 | require.NoError(t, err)
41 | assert.Equal(t, "bar.jpg", filename)
42 | assert.Equal(t, "TenToolBot (+https://github.com/dnovikoff/tenhou/tools/tentool)", userAgent)
43 | })
44 | }
45 |
--------------------------------------------------------------------------------
/vendor/github.com/pmezard/go-difflib/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013, Patrick Mezard
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are
6 | met:
7 |
8 | Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 | Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 | The names of its contributors may not be used to endorse or promote
14 | products derived from this software without specific prior written
15 | permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
23 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/hand/calc/meld_kokushi.go:
--------------------------------------------------------------------------------
1 | package calc
2 |
3 | import (
4 | "sort"
5 |
6 | "github.com/dnovikoff/tempai-core/compact"
7 | "github.com/dnovikoff/tempai-core/tile"
8 | )
9 |
10 | type kokushi struct {
11 | meld
12 | hole tile.Tile
13 | }
14 |
15 | var kokushi13waits = compact.TerminalOrHonor.Tiles()
16 |
17 | var kokushi13meld = &kokushi{meld{
18 | tags: TagKoksuhi13 | TagKokushi,
19 | waits: kokushi13waits,
20 | cwaits: compact.TerminalOrHonor,
21 | tiles: kokushi13waits,
22 | }, tile.TileNull}
23 |
24 | func KokushiComplete(p tile.Tile) Meld {
25 | hand := kokushi13waits.Clone()
26 | hand = append(hand, p)
27 | sort.Sort(hand)
28 | return &kokushi{meld{
29 | t: p,
30 | tags: TagKokushi | TagComplete,
31 | tiles: hand,
32 | }, tile.TileNull}
33 | }
34 |
35 | func Kokushi13() Meld {
36 | return kokushi13meld
37 | }
38 |
39 | func KokushiMeld(pair tile.Tile, wait tile.Tile) Meld {
40 | x := kokushi13waits.Clone()
41 | for k, v := range x {
42 | if v == wait {
43 | x[k] = pair
44 | }
45 | }
46 | sort.Sort(x)
47 | return &kokushi{meld{
48 | tags: TagKokushi,
49 | waits: tile.Tiles{wait},
50 | cwaits: compact.FromTile(wait),
51 | t: pair,
52 | tiles: x,
53 | }, wait}
54 | }
55 |
56 | func (*kokushi) Extract(Counters) bool {
57 | panic("kokushi.Extract not implemented")
58 | }
59 |
60 | func (k *kokushi) Complete(t tile.Tile) Meld {
61 | if !k.cwaits.Check(t) {
62 | return nil
63 | }
64 | if k.hole == t {
65 | return KokushiComplete(k.t)
66 | }
67 | return KokushiComplete(t)
68 | }
69 |
--------------------------------------------------------------------------------
/parser/agari.go:
--------------------------------------------------------------------------------
1 | package parser
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/dnovikoff/tempai-core/score"
7 | "github.com/dnovikoff/tempai-core/yaku"
8 | "github.com/dnovikoff/tenhou/tbase"
9 | )
10 |
11 | func ParseAgari(node *Node) (result *tbase.Agari, err error) {
12 | agari := &tbase.Agari{}
13 | agari.Who = node.GetWho()
14 | agari.Status, err = node.GetTableStatus()
15 | if err != nil {
16 | return
17 | }
18 | agari.From = node.GetOpponent("fromWho")
19 | if node.Check("paoWho") {
20 | x := node.GetOpponent("paoWho")
21 | agari.Pao = &x
22 | }
23 | ints := node.IntList("ten")
24 | if len(ints) != 3 {
25 | err = fmt.Errorf("ten length for agari should be 3 != %v", len(ints))
26 | return
27 | }
28 | agari.Score = tbase.Score{
29 | yaku.FuPoints(ints[0]),
30 | score.Money(ints[1]),
31 | score.RiichiSticks(ints[2])}
32 | agari.Changes = node.GetScoreChanges()
33 | agari.Hand = node.GetHai("hai")
34 | agari.DoraIndicators = node.GetHai("doraHai")
35 | agari.UraIndicators = node.GetHai("doraHaiUra")
36 |
37 | agari.WinTile = node.GetInstance("machi")
38 | agari.FinalScores = node.GetFinalScores()
39 |
40 | agari.Yakumans = tbase.YakumansFromInts(node.IntList("yakuman"))
41 | agari.Yakus = tbase.YakusFromInts(node.IntList("yaku"))
42 |
43 | ints = node.IntList("m")
44 | if len(ints) > 0 {
45 | melds := make(tbase.Melds, len(ints))
46 | for k, v := range ints {
47 | melds[k] = tbase.Meld(v)
48 | }
49 | agari.Melds = melds
50 | }
51 | agari.Ratio = node.String("ratio")
52 | agari.Chips = node.IntList("chip")
53 | result = agari
54 | return
55 | }
56 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018 The Go Authors. All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are
5 | met:
6 |
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above
10 | copyright notice, this list of conditions and the following disclaimer
11 | in the documentation and/or other materials provided with the
12 | distribution.
13 | * Neither the name of Google Inc. nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/vendor/github.com/golang/protobuf/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2010 The Go Authors. All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are
5 | met:
6 |
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 | * Redistributions in binary form must reproduce the above
10 | copyright notice, this list of conditions and the following disclaimer
11 | in the documentation and/or other materials provided with the
12 | distribution.
13 | * Neither the name of Google Inc. nor the names of its
14 | contributors may be used to endorse or promote products derived from
15 | this software without specific prior written permission.
16 |
17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 |
--------------------------------------------------------------------------------
/cmd/pimboo-server/game/player.go:
--------------------------------------------------------------------------------
1 | package game
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/compact"
5 | "github.com/dnovikoff/tempai-core/hand/calc"
6 | "github.com/dnovikoff/tempai-core/hand/tempai"
7 | "github.com/dnovikoff/tempai-core/score"
8 | "github.com/dnovikoff/tempai-core/tile"
9 | "github.com/dnovikoff/tempai-core/yaku"
10 | "github.com/dnovikoff/tenhou/tbase"
11 | )
12 |
13 | type Player struct {
14 | Hand compact.Instances
15 | Melds tbase.CalledList
16 | Discard compact.Instances
17 | Score score.Money
18 | tempai *tempai.TempaiResults
19 | furiten bool
20 | first bool
21 | }
22 |
23 | func NewPlayer(x score.Money) *Player {
24 | return &Player{Score: x}
25 | }
26 |
27 | func (p *Player) Waits() compact.Tiles {
28 | return tempai.GetWaits(p.tempai)
29 | }
30 |
31 | func (p *Player) update() {
32 | p.tempai = tempai.Calculate(p.Hand, calc.Declared(p.Melds.Core()))
33 |
34 | checker := p.Discard.UniqueTiles()
35 | p.furiten = (checker & p.Waits()) != 0
36 | }
37 |
38 | func (p *Player) win(ctx *yaku.Context) *yaku.Result {
39 | ctx.IsFirstTake = p.first
40 | ctx.Rules = rules
41 | return yaku.Win(p.tempai, ctx, nil)
42 | }
43 |
44 | func (p *Player) drop(t tile.Instance) {
45 | p.first = false
46 | p.Hand.Remove(t)
47 | p.Discard.Set(t)
48 | p.update()
49 | }
50 |
51 | func (p *Player) take(t tile.Instance) bool {
52 | p.Hand.Set(t)
53 | return p.Waits().Check(t.Tile())
54 | }
55 |
56 | func (p *Player) Init(hand compact.Instances) {
57 | p.Hand = hand
58 | p.Melds = nil
59 | p.first = true
60 | p.Discard = compact.NewInstances()
61 | p.update()
62 | }
63 |
--------------------------------------------------------------------------------
/tbase/lobby.go:
--------------------------------------------------------------------------------
1 | package tbase
2 |
3 | import (
4 | "bytes"
5 | "fmt"
6 | )
7 |
8 | type LobbyRules int
9 |
10 | const (
11 | FlagOnline LobbyRules = 1 << iota
12 | FlagNoAkkas
13 | FlagNoKuitan
14 | FlagHanchan
15 | Flag3Man
16 | FlagDan1
17 | FlagFast
18 | FlagDan2
19 | FlagEnd
20 | )
21 |
22 | const (
23 | MaskDanAll LobbyRules = FlagDan1 | FlagDan2
24 | MaskDanKu LobbyRules = 0
25 | MaskDan1 = FlagDan1
26 | MaskDan2 = FlagDan2
27 | MaskDanPhoenix = MaskDan1 | MaskDan2
28 |
29 | RulesDzjanso LobbyRules = 0x0841
30 | )
31 |
32 | func (r LobbyRules) Extract(mask LobbyRules) LobbyRules {
33 | return r & mask
34 | }
35 |
36 | func (r LobbyRules) Check(f LobbyRules) bool {
37 | return (f & r) == f
38 | }
39 |
40 | func (r LobbyRules) String() string {
41 | return fmt.Sprintf("%04x", int(r))
42 | }
43 |
44 | func (r LobbyRules) DebugString() string {
45 | buf := &bytes.Buffer{}
46 | w := func(x LobbyRules, t string, f string) {
47 | if r.Check(x) {
48 | fmt.Fprint(buf, t)
49 | } else {
50 | fmt.Fprint(buf, f)
51 | }
52 | }
53 | w(FlagNoAkkas, "a", "A")
54 | w(FlagNoKuitan, "k", "K")
55 | w(FlagHanchan, "H", "T")
56 | w(Flag3Man, "3", "4")
57 | w(FlagFast, "F", "f")
58 | dan := r.Extract(MaskDanAll)
59 | switch dan {
60 | case MaskDanKu:
61 | fmt.Fprintf(buf, "0")
62 | case MaskDan1:
63 | fmt.Fprintf(buf, "D")
64 | case MaskDan2:
65 | fmt.Fprintf(buf, "U")
66 | case MaskDanPhoenix:
67 | fmt.Fprintf(buf, "X")
68 | default:
69 | fmt.Fprintf(buf, "[Strange value %b]", dan)
70 | }
71 | return string(buf.Bytes())
72 | }
73 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/encoding/text/doc.go:
--------------------------------------------------------------------------------
1 | // Copyright 2018 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | // Package text implements the text format for protocol buffers.
6 | // This package has no semantic understanding for protocol buffers and is only
7 | // a parser and composer for the format.
8 | //
9 | // There is no formal specification for the protobuf text format, as such the
10 | // C++ implementation (see google::protobuf::TextFormat) is the reference
11 | // implementation of the text format.
12 | //
13 | // This package is neither a superset nor a subset of the C++ implementation.
14 | // This implementation permits a more liberal grammar in some cases to be
15 | // backwards compatible with the historical Go implementation.
16 | // Future parsings unique to Go should not be added.
17 | // Some grammars allowed by the C++ implementation are deliberately
18 | // not implemented here because they are considered a bug by the protobuf team
19 | // and should not be replicated.
20 | //
21 | // The Go implementation should implement a sufficient amount of the C++
22 | // grammar such that the default text serialization by C++ can be parsed by Go.
23 | // However, just because the C++ parser accepts some input does not mean that
24 | // the Go implementation should as well.
25 | //
26 | // The text format is almost a superset of JSON except:
27 | // - message keys are not quoted strings, but identifiers
28 | // - the top-level value must be a message without the delimiters
29 | package text
30 |
--------------------------------------------------------------------------------
/parser/node_reader.go:
--------------------------------------------------------------------------------
1 | package parser
2 |
3 | import (
4 | "context"
5 | "errors"
6 | "sync"
7 | )
8 |
9 | type readResult struct {
10 | node Node
11 | err error
12 | }
13 |
14 | type NodeReader struct {
15 | resultCh chan readResult
16 | ReadCallback func(context.Context) (string, error)
17 | }
18 |
19 | func NewNodeReader() *NodeReader {
20 | ch := make(chan readResult)
21 | // Create with closed channel for correct errors
22 | close(ch)
23 | return &NodeReader{resultCh: ch}
24 |
25 | }
26 |
27 | func (r *NodeReader) run(ctx context.Context) {
28 | ctx, cancel := context.WithCancel(ctx)
29 | defer func() {
30 | cancel()
31 | close(r.resultCh)
32 | }()
33 | for {
34 | message, err := r.ReadCallback(ctx)
35 | if err != nil {
36 | r.resultCh <- readResult{err: err}
37 | return
38 | }
39 | select {
40 | case <-ctx.Done():
41 | return
42 | default:
43 | }
44 | nodes, err := ParseXML(message)
45 | if err != nil {
46 | r.resultCh <- readResult{err: err}
47 | return
48 | }
49 | for _, v := range nodes {
50 | r.resultCh <- readResult{v, nil}
51 | }
52 | }
53 | }
54 |
55 | func (r *NodeReader) Start(ctx context.Context) func() {
56 | r.resultCh = make(chan readResult, 1024)
57 | var wg sync.WaitGroup
58 | wg.Add(1)
59 | go func() {
60 | r.run(ctx)
61 | wg.Done()
62 | }()
63 | return wg.Wait
64 | }
65 |
66 | func (r *NodeReader) Next() (node *Node, err error) {
67 | res, ok := <-r.resultCh
68 | if !ok {
69 | err = errors.New("NodeReader stopped")
70 | return
71 | }
72 | if res.err != nil {
73 | err = res.err
74 | return
75 | }
76 | node = &res.node
77 | return
78 | }
79 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/proto/proto.go:
--------------------------------------------------------------------------------
1 | // Copyright 2018 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package proto
6 |
7 | import (
8 | "google.golang.org/protobuf/internal/errors"
9 | "google.golang.org/protobuf/reflect/protoreflect"
10 | )
11 |
12 | // Message is the top-level interface that all messages must implement.
13 | // It provides access to a reflective view of a message.
14 | // Any implementation of this interface may be used with all functions in the
15 | // protobuf module that accept a Message, except where otherwise specified.
16 | //
17 | // This is the v2 interface definition for protobuf messages.
18 | // The v1 interface definition is [github.com/golang/protobuf/proto.Message].
19 | //
20 | // - To convert a v1 message to a v2 message,
21 | // use [google.golang.org/protobuf/protoadapt.MessageV2Of].
22 | // - To convert a v2 message to a v1 message,
23 | // use [google.golang.org/protobuf/protoadapt.MessageV1Of].
24 | type Message = protoreflect.ProtoMessage
25 |
26 | // Error matches all errors produced by packages in the protobuf module
27 | // according to [errors.Is].
28 | //
29 | // Example usage:
30 | //
31 | // if errors.Is(err, proto.Error) { ... }
32 | var Error error
33 |
34 | func init() {
35 | Error = errors.Error
36 | }
37 |
38 | // MessageName returns the full name of m.
39 | // If m is nil, it returns an empty string.
40 | func MessageName(m Message) protoreflect.FullName {
41 | if m == nil {
42 | return ""
43 | }
44 | return m.ProtoReflect().Descriptor().FullName()
45 | }
46 |
--------------------------------------------------------------------------------
/vendor/github.com/facebookgo/stack/license:
--------------------------------------------------------------------------------
1 | BSD License
2 |
3 | For stack software
4 |
5 | Copyright (c) 2015, Facebook, Inc. All rights reserved.
6 |
7 | Redistribution and use in source and binary forms, with or without modification,
8 | are permitted provided that the following conditions are met:
9 |
10 | * Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | * Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | * Neither the name Facebook nor the names of its contributors may be used to
18 | endorse or promote products derived from this software without specific
19 | prior written permission.
20 |
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
25 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/cobra/.golangci.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2013-2023 The Cobra Authors
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | run:
16 | deadline: 5m
17 |
18 | linters:
19 | disable-all: true
20 | enable:
21 | #- bodyclose
22 | # - deadcode ! deprecated since v1.49.0; replaced by 'unused'
23 | #- depguard
24 | #- dogsled
25 | #- dupl
26 | - errcheck
27 | #- exhaustive
28 | #- funlen
29 | #- gochecknoinits
30 | - goconst
31 | - gocritic
32 | #- gocyclo
33 | - gofmt
34 | - goimports
35 | #- gomnd
36 | #- goprintffuncname
37 | - gosec
38 | - gosimple
39 | - govet
40 | - ineffassign
41 | #- lll
42 | - misspell
43 | #- nakedret
44 | #- noctx
45 | - nolintlint
46 | #- rowserrcheck
47 | #- scopelint
48 | - staticcheck
49 | #- structcheck ! deprecated since v1.49.0; replaced by 'unused'
50 | - stylecheck
51 | #- typecheck
52 | - unconvert
53 | #- unparam
54 | - unused
55 | # - varcheck ! deprecated since v1.49.0; replaced by 'unused'
56 | #- whitespace
57 | fast: false
58 |
--------------------------------------------------------------------------------
/vendor/github.com/spf13/pflag/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012 Alex Ogier. All rights reserved.
2 | Copyright (c) 2012 The Go Authors. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are
6 | met:
7 |
8 | * Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 | * Redistributions in binary form must reproduce the above
11 | copyright notice, this list of conditions and the following disclaimer
12 | in the documentation and/or other materials provided with the
13 | distribution.
14 | * Neither the name of Google Inc. nor the names of its
15 | contributors may be used to endorse or promote products derived from
16 | this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 |
--------------------------------------------------------------------------------
/protoc.mk:
--------------------------------------------------------------------------------
1 | protoc_version := 30.2
2 | protoc_dir := gobin/protoc/v$(protoc_version)
3 | protoc_bin := $(protoc_dir)/bin/protoc
4 | protoc_gen_go := gobin/protoc-gen-go
5 |
6 | ifeq ($(OS),Windows_NT)
7 | protoc_bin := $(protoc_bin).exe
8 | ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
9 | protocarch := win64
10 | else
11 | protocarch := win32
12 | endif
13 | else
14 | uname_s := $(shell uname)
15 | uname_m := $(shell uname -m)
16 | ifeq ($(uname_s),Linux)
17 | pos := linux
18 | else ifeq ($(uname_s),Darwin)
19 | pos := osx
20 | else
21 | $(error Unknown os $(uname_s))
22 | endif
23 | ifeq ($(uname_m),x86_64)
24 | protocarch := $(pos)-x86_64
25 | else
26 | protocarch := $(pos)-x86_32
27 | endif
28 | endif
29 |
30 | protoc_include := $(protoc_dir)/include
31 | protoc_zip_name := protoc-$(protoc_version)-$(protocarch).zip
32 | protoc_url := https://github.com/google/protobuf/releases/download/v$(protoc_version)/$(protoc_zip_name)
33 | protoc_zip_output := gobin/$(protoc_zip_name)
34 |
35 | $(protoc_bin):
36 | rm -rf $(protoc_dir)
37 | mkdir -p $(protoc_dir)
38 | curl --retry 5 -L $(protoc_url) -o $(protoc_zip_output)
39 | unzip $(protoc_zip_output) -d $(protoc_dir)
40 | rm $(protoc_zip_output)
41 | touch $(protoc_bin) # override time from zip
42 |
43 | # Ignore timestamp
44 | protoc-bin: | $(protoc_bin)
45 |
46 | $(protoc_gen_go): $(protoc_bin)
47 | go build -mod vendor -o $@ ./vendor/github.com/golang/protobuf/protoc-gen-go
48 |
49 | protoc_cmd := $(protoc_bin) -I $(protoc_include) -I ./proto
50 | protoc_go_cmd := $(protoc_cmd) --plugin=protoc-gen-go=$(protoc_gen_go)
51 |
--------------------------------------------------------------------------------
/vendor/github.com/facebookgo/stackerr/license:
--------------------------------------------------------------------------------
1 | BSD License
2 |
3 | For stackerr software
4 |
5 | Copyright (c) 2015, Facebook, Inc. All rights reserved.
6 |
7 | Redistribution and use in source and binary forms, with or without modification,
8 | are permitted provided that the following conditions are met:
9 |
10 | * Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | * Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | * Neither the name Facebook nor the names of its contributors may be used to
18 | endorse or promote products derived from this software without specific
19 | prior written permission.
20 |
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
25 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
--------------------------------------------------------------------------------
/parser/xml.go:
--------------------------------------------------------------------------------
1 | package parser
2 |
3 | import (
4 | "encoding/xml"
5 |
6 | "github.com/facebookgo/stackerr"
7 |
8 | "github.com/dnovikoff/tenhou/tbase"
9 | )
10 |
11 | type Nodes []Node
12 |
13 | type Root struct {
14 | XMLName xml.Name `xml:"mjloggm"`
15 | Nodes Nodes `xml:",any"`
16 | }
17 |
18 | func (node *Node) GetInit() (x tbase.Init, err error) {
19 | x.Seed, err = ParseSeed(node.String("seed"))
20 | if err != nil {
21 | return
22 | }
23 | x.Dealer = node.GetDealer()
24 | x.Scores = node.GetScores()
25 | x.Chip = node.IntList("chip")
26 | return
27 | }
28 |
29 | func ParseRyuukyoku(node *Node) (r *tbase.Ryuukyoku, err error) {
30 | t := node.String("type")
31 | dt := tbase.DrawMap[t]
32 | if dt == tbase.DrawUnknown {
33 | err = stackerr.Newf("Unknown draw type '%s'", t)
34 | return
35 | }
36 | status, err := node.GetTableStatus()
37 | if err != nil {
38 | return
39 | }
40 | r = &tbase.Ryuukyoku{}
41 | r.ScoreChanges = node.GetScoreChanges()
42 | r.Hands = node.GetHands()
43 | r.Finals = node.GetFinalScores()
44 | r.TableStatus = status
45 | r.DrawType = dt
46 | r.Ratio = node.IntList("ratio")
47 | return
48 | }
49 |
50 | func (node *Node) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
51 | t, err := d.Token()
52 | if err != nil {
53 | return err
54 | }
55 | switch t.(type) {
56 | case xml.EndElement:
57 | default:
58 | return stackerr.Newf("Unexpected element %v", t)
59 | }
60 |
61 | node.Name = start.Name.Local
62 | attrs := make(map[string]string, len(start.Attr))
63 | for _, x := range start.Attr {
64 | attrs[x.Name.Local] = x.Value
65 | }
66 | node.Attributes = attrs
67 | return nil
68 | }
69 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/hand/calc/melds.go:
--------------------------------------------------------------------------------
1 | package calc
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/tile"
5 | )
6 |
7 | type Melds []Meld
8 |
9 | func (m Melds) Clone() Melds {
10 | x := make(Melds, len(m))
11 | for k, v := range m {
12 | x[k] = v
13 | }
14 | return x
15 | }
16 |
17 | func createAllPon() Melds {
18 | x := make(Melds, 0, tile.TileCount)
19 | for i := tile.TileBegin; i < tile.TileEnd; i++ {
20 | x = append(x, Pon(i))
21 | }
22 | return x
23 | }
24 |
25 | func createAllPonParts() Melds {
26 | x := make(Melds, 0, tile.TileCount)
27 | for i := tile.TileBegin; i < tile.TileEnd; i++ {
28 | x = append(x, PonPart(i))
29 | }
30 | return x
31 | }
32 |
33 | func createAllChi() Melds {
34 | x := make(Melds, 0, int(tile.SequenceEnd-tile.SequenceBegin))
35 | for i := tile.SequenceBegin; i < tile.SequenceEnd; i++ {
36 | c := Chi(i)
37 | if c == nil {
38 | continue
39 | }
40 | x = append(x, c)
41 | }
42 | return x
43 | }
44 |
45 | func createAllChiParts() Melds {
46 | x := make(Melds, 0, int(tile.SequenceEnd-tile.SequenceBegin)*3)
47 | for i := tile.SequenceBegin; i < tile.SequenceEnd; i++ {
48 | m := ChiPart1(i)
49 | if m != nil {
50 | x = append(x, m)
51 | }
52 | m = ChiPart2(i)
53 | if m != nil {
54 | x = append(x, m)
55 | }
56 | }
57 | return x
58 | }
59 |
60 | func CreateComplete() Melds {
61 | return append(createAllChi(),
62 | createAllPon()...)
63 | }
64 |
65 | func CreateParts() Melds {
66 | return append(
67 | createAllChiParts(),
68 | createAllPonParts()...)
69 | }
70 |
71 | func CreateAll() Melds {
72 | return append(
73 | CreateParts(),
74 | CreateComplete()...)
75 | }
76 |
--------------------------------------------------------------------------------
/tools/tentool/utils/scheduler.go:
--------------------------------------------------------------------------------
1 | package utils
2 |
3 | type Task interface {
4 | // Called on one of worker routine
5 | Run() error
6 | // Called on single routine
7 | Save(blocked bool) error
8 | }
9 |
10 | type Scheduler struct {
11 | routines Routines
12 | bgRoutines Routines
13 | tasks chan Task
14 | save chan Task
15 | }
16 |
17 | func (s *Scheduler) Start(cnt, saveSize int) {
18 | s.tasks = make(chan Task, cnt)
19 | s.save = make(chan Task, saveSize)
20 | for i := 0; i < cnt; i++ {
21 | s.routines.Start(func() error {
22 | for t := range s.tasks {
23 | err := t.Run()
24 | if err != nil {
25 | return err
26 | }
27 | }
28 | return nil
29 | })
30 | }
31 | s.bgRoutines.Start(s.saveRoutine)
32 | }
33 |
34 | func (s *Scheduler) saveRoutine() error {
35 | for {
36 | t, blocked := s.readForSave()
37 | if t == nil {
38 | return nil
39 | }
40 | err := t.Save(blocked)
41 | if err != nil {
42 | return err
43 | }
44 | }
45 | return nil
46 | }
47 |
48 | func (s *Scheduler) readForSave() (Task, bool) {
49 | var t Task
50 | blocked := false
51 | select {
52 | case t = <-s.save:
53 | default:
54 | t = <-s.save
55 | blocked = true
56 | }
57 | return t, blocked
58 | }
59 |
60 | func (s *Scheduler) Stop() error {
61 | close(s.tasks)
62 | err := s.routines.Wait()
63 | close(s.save)
64 | bgErr := s.bgRoutines.Wait()
65 | if err != nil {
66 | return err
67 | }
68 | return bgErr
69 | }
70 |
71 | func (s *Scheduler) Push(t Task) {
72 | s.tasks <- t
73 | }
74 |
75 | func (s *Scheduler) Error() error {
76 | err := s.routines.Error()
77 | if err != nil {
78 | return err
79 | }
80 | return s.bgRoutines.Error()
81 | }
82 |
--------------------------------------------------------------------------------
/tools/tentool/stats/index.go:
--------------------------------------------------------------------------------
1 | package stats
2 |
3 | import (
4 | "os"
5 | "sort"
6 |
7 | "go.uber.org/multierr"
8 |
9 | "github.com/dnovikoff/tenhou/tools/tentool/utils"
10 | )
11 |
12 | type FileIndex struct {
13 | utils.JSONGZFile
14 | data map[string]string
15 | }
16 |
17 | func NewFileIndex(p string) *FileIndex {
18 | x := &FileIndex{data: map[string]string{}}
19 | x.Path = p
20 | return x
21 | }
22 |
23 | func (i *FileIndex) Load() error {
24 | return i.JSONGZFile.Load(&i.data)
25 | }
26 |
27 | func (i *FileIndex) Save() (err error) {
28 | return i.JSONGZFile.Save(i.data)
29 | }
30 |
31 | func (i *FileIndex) JustAdd(url, path string) {
32 | i.data[url] = path
33 | }
34 |
35 | func (i *FileIndex) Add(url, path string) error {
36 | i.JustAdd(url, path)
37 | return i.Save()
38 | }
39 |
40 | func (i *FileIndex) Check(url string) bool {
41 | _, found := i.data[url]
42 | return found
43 | }
44 |
45 | func (i *FileIndex) Len() int {
46 | return len(i.data)
47 | }
48 |
49 | func (i *FileIndex) Files() []string {
50 | out := make([]string, 0, len(i.data))
51 | for _, v := range i.data {
52 | out = append(out, v)
53 | }
54 | sort.Strings(out)
55 | return out
56 | }
57 |
58 | func (i *FileIndex) Validate() error {
59 | var total error
60 | checked := make(map[string]bool, len(i.data))
61 | for k, v := range i.data {
62 | found, ok := checked[v]
63 | if !ok {
64 | _, err := os.Stat(v)
65 | if err != nil {
66 | total = multierr.Append(total, err)
67 | checked[v] = false
68 | found = false
69 | } else {
70 | checked[v] = true
71 | found = true
72 | }
73 | }
74 | if !found {
75 | delete(i.data, k)
76 | }
77 | }
78 | return total
79 | }
80 |
--------------------------------------------------------------------------------
/network/xml_connection.go:
--------------------------------------------------------------------------------
1 | package network
2 |
3 | import (
4 | "bufio"
5 | "context"
6 | "errors"
7 | "io"
8 | "net"
9 | "strings"
10 | )
11 |
12 | const terminator = byte(0)
13 |
14 | type XMLConnection interface {
15 | io.Closer
16 | Read(context.Context) (string, error)
17 | Write(context.Context, string) error
18 | }
19 |
20 | type xmlConnection struct {
21 | impl net.Conn
22 | reader *bufio.Reader
23 | }
24 |
25 | var _ XMLConnection = &xmlConnection{}
26 |
27 | func NewXMLConnection(impl net.Conn) *xmlConnection {
28 | return &xmlConnection{
29 | impl: impl,
30 | reader: bufio.NewReader(impl),
31 | }
32 | }
33 |
34 | // Not thread safe
35 | func (c *xmlConnection) Read(ctx context.Context) (str string, err error) {
36 | type result struct {
37 | str string
38 | err error
39 | }
40 | ch := make(chan *result, 1)
41 | go func() {
42 | var r result
43 | r.str, r.err = c.reader.ReadString(terminator)
44 | r.str = strings.TrimRight(r.str, string([]byte{terminator}))
45 | ch <- &r
46 | }()
47 | select {
48 | case <-ctx.Done():
49 | err = errors.New("Read timeout exceded")
50 | c.impl.Close()
51 | case r := <-ch:
52 | str, err = r.str, r.err
53 | }
54 | return
55 | }
56 |
57 | func (c *xmlConnection) Close() error {
58 | return c.impl.Close()
59 | }
60 |
61 | // Not thread safe
62 | func (c *xmlConnection) Write(ctx context.Context, str string) (err error) {
63 | ch := make(chan error, 1)
64 | go func() {
65 | _, writeError := c.impl.Write(append([]byte(str), terminator))
66 | ch <- writeError
67 | }()
68 | select {
69 | case <-ctx.Done():
70 | err = errors.New("Write timeout exceded")
71 | c.impl.Close()
72 | case err = <-ch:
73 | }
74 | return
75 | }
76 |
--------------------------------------------------------------------------------
/tools/tentool/stats/test_data/sce.log:
--------------------------------------------------------------------------------
1 | 00:10 | 02 | 四技-喰赤- | 牌譜 | DERESUKE(+3.7) 放銃王4(-0.7) 豪雪地帯(-1.3) 〓アナスタシア〓(-1.7)
2 | 00:13 | 01 | 四技-喰赤- | 牌譜 | 豪雪地帯(+8.0) 放銃王4(0.0) 〓アナスタシア〓(0.0) DERESUKE(-8.0)
3 | 00:14 | 01 | 四技-喰赤- | 牌譜 | 豪雪地帯(+1.5) DERESUKE(0.0) 〓アナスタシア〓(0.0) 放銃王4(-1.5)
4 | 00:16 | 01 | 四技-喰赤- | 牌譜 | 豪雪地帯(+18.0) DERESUKE(0.0) 放銃王4(0.0) 〓アナスタシア〓(-18.0)
5 | 00:18 | 03 | 四技-喰赤- | 牌譜 | 豪雪地帯(+3.0) 〓アナスタシア〓(-1.0) DERESUKE(-1.0) 放銃王4(-1.0)
6 | 00:21 | 01 | 四技-喰赤- | 牌譜 | 初心者です(+2.6) 〓アナスタシア〓(0.0) 放銃王4(0.0) DERESUKE(-2.6)
7 | 00:23 | 02 | 四技-喰赤- | 牌譜 | 〓アナスタシア〓(+1.3) 放銃王4(0.0) DERESUKE(0.0) 初心者です(-1.3)
8 | 00:26 | 02 | 四技-喰赤- | 牌譜 | 〓アナスタシア〓(+2.9) 放銃王4(0.0) 初心者です(0.0) DERESUKE(-2.9)
9 | 00:28 | 01 | 四技-喰赤- | 牌譜 | 〓アナスタシア〓(+2.9) DERESUKE(0.0) 初心者です(0.0) 放銃王4(-2.9)
10 | 00:29 | 02 | 四技-喰赤- | 牌譜 | 〓アナスタシア〓(+8.7) DERESUKE(0.0) 放銃王4(0.0) 初心者です(-8.7)
11 | 00:33 | 01 | 四技-喰赤- | 牌譜 | ライジンファイト(+2.6) みやこん10歳(0.0) DERESUKE(0.0) 〓アナスタシア〓(-2.6)
--------------------------------------------------------------------------------
/network/examples/second.log:
--------------------------------------------------------------------------------
1 | Send:
2 | Get:
3 | Send:
4 | Get:
5 | Get:
6 | Send:
7 | Get:
8 | Get:
9 | Get:
10 | Get:
11 | Send:
12 | Get:
13 | Get:
14 | Get:
15 | Get:
16 | Get:
17 | Send:
18 | Get:
19 | Get:
20 | Get:
21 | Get:
22 | Send:
23 | Get:
24 | Get:
25 | Get:
26 | Get:
27 | Send:
28 | Get:
29 | Send:
30 | Get:
31 | Get:
32 | Get:
33 | Get:
34 | Send:
35 | Get:
36 | Get:
37 | Get:
38 | Get:
39 | Get:
40 | Get:
41 | Send:
42 | Get:
43 | Get:
44 | Get:
45 | Get:
46 | Get:
47 | Get:
48 | Get:
49 | Send:
--------------------------------------------------------------------------------
/tbase/meld_encode.go:
--------------------------------------------------------------------------------
1 | package tbase
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/dnovikoff/tempai-core/tile"
7 | )
8 |
9 | func EncodeCalled(in *Called) Meld {
10 | switch in.Type {
11 | case Kan, ClosedKan:
12 | return encodeKan(in)
13 | case Pon, UpgrdedKan:
14 | return encodeSame(in)
15 | case Chi:
16 | return encodeChi(in)
17 | }
18 | panic(fmt.Sprintf("Unexpected type %v", in.Type))
19 | }
20 |
21 | func EncodeCalledList(in CalledList) Melds {
22 | x := make(Melds, len(in))
23 | for k, v := range in {
24 | x[k] = EncodeCalled(v)
25 | }
26 | return x
27 | }
28 |
29 | func encodeSame(in *Called) Meld {
30 | cp := in.Called.CopyID()
31 | if cp > in.Upgraded.CopyID() {
32 | cp--
33 | }
34 | base := in.Called.Tile() - tile.TileBegin
35 | m := Meld(base)*3 + Meld(cp)
36 | m = (m << 2)
37 | m = (m << 2) | Meld(in.Upgraded.CopyID())
38 | m = (m << 1)
39 | if in.Type == UpgrdedKan {
40 | m |= 1
41 | }
42 | m = (m << 1)
43 | if in.Type != UpgrdedKan {
44 | m |= 1
45 | }
46 | m = (m << 1)
47 | m = (m << 2) | Meld(in.Opponent)
48 | return m
49 | }
50 |
51 | func encodeKan(in *Called) Meld {
52 | m := Meld(in.Called.Tile()-tile.TileBegin)*4 + Meld(in.Called.CopyID())
53 | m = (m << 6)
54 | m = (m << 2) | Meld(in.Opponent)
55 | return m
56 | }
57 |
58 | func encodeChi(in *Called) Meld {
59 | base := in.Core.Tile() - tile.TileBegin
60 | calledIndex := int(in.Called.Tile() - in.Core.Tile())
61 | tiles := in.Tiles
62 |
63 | m := Meld(int((base/9)*7+base%9)*3 + calledIndex)
64 | m = (m << 1)
65 | m = (m << 2) | Meld(tiles[2].CopyID())
66 | m = (m << 2) | Meld(tiles[1].CopyID())
67 | m = (m << 2) | Meld(tiles[0].CopyID())
68 | m = (m << 1) | 1
69 | m = (m << 2) | Meld(in.Opponent)
70 | return m
71 | }
72 |
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/compact/totals.go:
--------------------------------------------------------------------------------
1 | package compact
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/tile"
5 | )
6 |
7 | type Totals []int
8 |
9 | func NewTotals() Totals {
10 | return make(Totals, tile.TileCount)
11 | }
12 |
13 | func (ts Totals) Merge(in Instances) Totals {
14 | if in == nil {
15 | return ts
16 | }
17 | in.Each(func(mask Mask) bool {
18 | ts.Add(mask.Tile(), mask.Count())
19 | return true
20 | })
21 | return ts
22 | }
23 |
24 | func (ts Totals) Count() int {
25 | c := 0
26 | for _, v := range ts {
27 | c += v
28 | }
29 | return c
30 | }
31 |
32 | func (ts Totals) Get(t tile.Tile) int {
33 | return ts[shift(t)]
34 | }
35 |
36 | func (ts Totals) Clone() Totals {
37 | x := NewTotals()
38 | for k, v := range ts {
39 | x[k] = v
40 | }
41 | return x
42 | }
43 |
44 | func (ts Totals) UniqueCount() int {
45 | c := 0
46 | for _, v := range ts {
47 | if v > 0 {
48 | c++
49 | }
50 | }
51 | return c
52 | }
53 |
54 | func (ts Totals) IsFull(t tile.Tile) bool {
55 | return ts[shift(t)] > 3
56 | }
57 |
58 | func (ts Totals) Set(t tile.Tile, d int) {
59 | ts[shift(t)] = d
60 | }
61 |
62 | func (ts Totals) Add(t tile.Tile, d int) {
63 | ts[shift(t)] += d
64 | }
65 |
66 | func (ts Totals) UniqueTiles() Tiles {
67 | ret := Tiles(0)
68 | for t, c := range ts {
69 | if c > 0 {
70 | ret = ret.Set(tile.Tile(t) + tile.TileBegin)
71 | }
72 | }
73 | return ret
74 | }
75 |
76 | func (ts Totals) FullTiles() Tiles {
77 | ret := Tiles(0)
78 | for t, c := range ts {
79 | if c > 3 {
80 | ret = ret.Set(tile.Tile(t) + tile.TileBegin)
81 | }
82 | }
83 | return ret
84 | }
85 |
86 | func (ts Totals) FreeTiles() Tiles {
87 | return (^ts.FullTiles()).Normalize()
88 | }
89 |
--------------------------------------------------------------------------------
/tbase/called.go:
--------------------------------------------------------------------------------
1 | package tbase
2 |
3 | import (
4 | "github.com/dnovikoff/tempai-core/compact"
5 | "github.com/dnovikoff/tempai-core/hand/calc"
6 | "github.com/dnovikoff/tempai-core/tile"
7 | )
8 |
9 | type Called struct {
10 | Type CallType
11 | Opponent Opponent
12 | Tiles tile.Instances
13 | Called tile.Instance
14 | Upgraded tile.Instance
15 | // Core representation of meld for tempai calculator
16 | Core calc.Meld
17 | }
18 |
19 | type CalledList []*Called
20 |
21 | func (cl CalledList) Core() calc.Melds {
22 | melds := make(calc.Melds, len(cl))
23 | for k, v := range cl {
24 | melds[k] = v.Core
25 | }
26 | return melds
27 | }
28 |
29 | func (cl CalledList) Add(x compact.Instances) {
30 | for _, v := range cl {
31 | v.Add(x)
32 | }
33 | }
34 |
35 | func (c *Called) Encode() Meld {
36 | return EncodeCalled(c)
37 | }
38 |
39 | func (c *Called) IsKan() bool {
40 | switch c.Type {
41 | case Kan, UpgrdedKan, ClosedKan:
42 | return true
43 | }
44 | return false
45 | }
46 |
47 | func (c *Called) Add(x compact.Instances) {
48 | x.Add(c.Tiles)
49 | if c.Called != tile.InstanceNull {
50 | x.Set(c.Called)
51 | }
52 | if c.Type == UpgrdedKan && c.Upgraded != tile.InstanceNull {
53 | x.Set(c.Upgraded)
54 | }
55 | }
56 |
57 | type CallType int
58 |
59 | const (
60 | Chi CallType = iota + 1
61 | Pon
62 | Kan
63 | ClosedKan
64 | UpgrdedKan
65 | )
66 |
67 | type Opponent int
68 |
69 | const (
70 | Self Opponent = iota
71 | Right
72 | Front
73 | Left
74 | )
75 |
76 | func (o Opponent) String() string {
77 | switch o {
78 | case Self:
79 | return "Self"
80 | case Right:
81 | return "Right"
82 | case Front:
83 | return "Front"
84 | case Left:
85 | return "Left"
86 | }
87 | return "Unknown"
88 | }
89 |
--------------------------------------------------------------------------------
/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go:
--------------------------------------------------------------------------------
1 | //go:build !testify_yaml_fail && !testify_yaml_custom
2 | // +build !testify_yaml_fail,!testify_yaml_custom
3 |
4 | // Package yaml is just an indirection to handle YAML deserialization.
5 | //
6 | // This package is just an indirection that allows the builder to override the
7 | // indirection with an alternative implementation of this package that uses
8 | // another implementation of YAML deserialization. This allows to not either not
9 | // use YAML deserialization at all, or to use another implementation than
10 | // [gopkg.in/yaml.v3] (for example for license compatibility reasons, see [PR #1120]).
11 | //
12 | // Alternative implementations are selected using build tags:
13 | //
14 | // - testify_yaml_fail: [Unmarshal] always fails with an error
15 | // - testify_yaml_custom: [Unmarshal] is a variable. Caller must initialize it
16 | // before calling any of [github.com/stretchr/testify/assert.YAMLEq] or
17 | // [github.com/stretchr/testify/assert.YAMLEqf].
18 | //
19 | // Usage:
20 | //
21 | // go test -tags testify_yaml_fail
22 | //
23 | // You can check with "go list" which implementation is linked:
24 | //
25 | // go list -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml
26 | // go list -tags testify_yaml_fail -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml
27 | // go list -tags testify_yaml_custom -f '{{.Imports}}' github.com/stretchr/testify/assert/yaml
28 | //
29 | // [PR #1120]: https://github.com/stretchr/testify/pull/1120
30 | package yaml
31 |
32 | import goyaml "gopkg.in/yaml.v3"
33 |
34 | // Unmarshal is just a wrapper of [gopkg.in/yaml.v3.Unmarshal].
35 | func Unmarshal(in []byte, out interface{}) error {
36 | return goyaml.Unmarshal(in, out)
37 | }
38 |
--------------------------------------------------------------------------------
/vendor/google.golang.org/protobuf/internal/impl/bitmap.go:
--------------------------------------------------------------------------------
1 | // Copyright 2024 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | //go:build !race
6 |
7 | package impl
8 |
9 | // There is no additional data as we're not running under race detector.
10 | type RaceDetectHookData struct{}
11 |
12 | // Empty stubs for when not using the race detector. Calls to these from index.go should be optimized away.
13 | func (presence) raceDetectHookPresent(num uint32) {}
14 | func (presence) raceDetectHookSetPresent(num uint32, size presenceSize) {}
15 | func (presence) raceDetectHookClearPresent(num uint32) {}
16 | func (presence) raceDetectHookAllocAndCopy(src presence) {}
17 |
18 | // raceDetectHookPresent is called by the generated file interface
19 | // (*proto.internalFuncs) Present to optionally read an unprotected
20 | // shadow bitmap when race detection is enabled. In regular code it is
21 | // a noop.
22 | func raceDetectHookPresent(field *uint32, num uint32) {}
23 |
24 | // raceDetectHookSetPresent is called by the generated file interface
25 | // (*proto.internalFuncs) SetPresent to optionally write an unprotected
26 | // shadow bitmap when race detection is enabled. In regular code it is
27 | // a noop.
28 | func raceDetectHookSetPresent(field *uint32, num uint32, size presenceSize) {}
29 |
30 | // raceDetectHookClearPresent is called by the generated file interface
31 | // (*proto.internalFuncs) ClearPresent to optionally write an unprotected
32 | // shadow bitmap when race detection is enabled. In regular code it is
33 | // a noop.
34 | func raceDetectHookClearPresent(field *uint32, num uint32) {}
35 |
--------------------------------------------------------------------------------
/vendor/go.uber.org/multierr/README.md:
--------------------------------------------------------------------------------
1 | # multierr [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov]
2 |
3 | `multierr` allows combining one or more Go `error`s together.
4 |
5 | ## Features
6 |
7 | - **Idiomatic**:
8 | multierr follows best practices in Go, and keeps your code idiomatic.
9 | - It keeps the underlying error type hidden,
10 | allowing you to deal in `error` values exclusively.
11 | - It provides APIs to safely append into an error from a `defer` statement.
12 | - **Performant**:
13 | multierr is optimized for performance:
14 | - It avoids allocations where possible.
15 | - It utilizes slice resizing semantics to optimize common cases
16 | like appending into the same error object from a loop.
17 | - **Interoperable**:
18 | multierr interoperates with the Go standard library's error APIs seamlessly:
19 | - The `errors.Is` and `errors.As` functions *just work*.
20 | - **Lightweight**:
21 | multierr comes with virtually no dependencies.
22 |
23 | ## Installation
24 |
25 | ```bash
26 | go get -u go.uber.org/multierr@latest
27 | ```
28 |
29 | ## Status
30 |
31 | Stable: No breaking changes will be made before 2.0.
32 |
33 | -------------------------------------------------------------------------------
34 |
35 | Released under the [MIT License].
36 |
37 | [MIT License]: LICENSE.txt
38 | [doc-img]: https://pkg.go.dev/badge/go.uber.org/multierr
39 | [doc]: https://pkg.go.dev/go.uber.org/multierr
40 | [ci-img]: https://github.com/uber-go/multierr/actions/workflows/go.yml/badge.svg
41 | [cov-img]: https://codecov.io/gh/uber-go/multierr/branch/master/graph/badge.svg
42 | [ci]: https://github.com/uber-go/multierr/actions/workflows/go.yml
43 | [cov]: https://codecov.io/gh/uber-go/multierr
44 |
--------------------------------------------------------------------------------
/cmd/tenhou-proxy/README.md:
--------------------------------------------------------------------------------
1 | ## Howto use proxy server
2 | I've made this small proxy for researching tenhou.net flash client protocol content.
3 |
4 | Download application
5 | ```
6 | go get -u github.com/dnovikoff/tenhou/cmd/tenhou-proxy
7 | ```
8 |
9 | Run application
10 | ```
11 | $GOPATH/bin/tenhou-proxy
12 | ```
13 |
14 | Add to your `hosts` file
15 | ```
16 | 127.0.0.1 b.mjv.jp
17 | ```
18 |
19 | Login into flash client http://tenhou.net/0/ .
20 | Application output would look like
21 | ```
22 | 2018/01/27 00:26:42 Started server on addr ':10080'. Sequence id is 'baab75ab'
23 | 2018/01/27 00:26:55 File for new connection is 'baab75ab_0001.log'
24 | 2018/01/27 00:26:55 Error: EOF
25 | 2018/01/27 00:26:55 Error: Read context done
26 | 2018/01/27 00:26:55 Done with 1
27 | 2018/01/27 00:26:55 File for new connection is 'baab75ab_0002.log'
28 | 2018/01/27 00:26:56 Error: EOF
29 | 2018/01/27 00:26:56 Error: Read context done
30 | 2018/01/27 00:26:56 Done with 2
31 | 2018/01/27 00:26:57 File for new connection is 'baab75ab_0003.log'
32 | ```
33 |
34 | Protocol logs will appear in workdir.
35 | Short example of log result.
36 | ```
37 | Send:
38 | Send:
39 | Get:
40 | Send:
41 | Send:
42 | Send:
43 | Get:
44 | Send:
45 | Get:
46 | Send:
47 | ```
--------------------------------------------------------------------------------
/proto/stats/stats.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | package stats;
3 |
4 | import "google/protobuf/timestamp.proto";
5 | import "google/protobuf/duration.proto";
6 |
7 | option go_package = "github.com/dnovikoff/tenhou/genproto/stats";
8 |
9 | enum LobbyType {
10 | LOBBY_TYPE_KU = 0; // 般
11 | LOBBY_TYPE_DAN = 1; // 上
12 | LOBBY_TYPE_UPPERDAN = 2; // 特
13 | LOBBY_TYPE_PHOENIX = 3; // 鳳
14 | LOBBY_TYPE_DZ = 4; // 技
15 | LOBBY_TYPE_X1 = 5; // 若
16 | LOBBY_TYPE_X2 = 6; // 銀
17 | LOBBY_TYPE_X3 = 7; // 琥
18 | LOBBY_TYPE_EXTERNAL = 8; // -
19 | }
20 |
21 | enum GameLength {
22 | GAME_LENGTH_SOUTH = 0;
23 | GAME_LENGTH_EAST = 1;
24 | GAME_LENGTH_ONE = 2;
25 | }
26 |
27 | enum GameType {
28 | GAME_TYPE_4 = 0;
29 | GAME_TYPE_3 = 1;
30 | }
31 |
32 | enum GameSpeed {
33 | GAME_SPEED_NORMAL = 0;
34 | GAME_SPEED_FAST = 1;
35 | }
36 |
37 | enum Akkas {
38 | AKKAS_YES = 0;
39 | AKKAS_NO = 1;
40 | }
41 |
42 | enum Tanyao {
43 | TANYAO_YES = 0;
44 | TANYAO_NO = 1;
45 | }
46 |
47 | enum NumberType {
48 | NO_NUMBER = 0;
49 | NUMBER_2 = 2;
50 | NUMBER_5 = 5;
51 | NUMBER_0 = 10;
52 | }
53 |
54 | message Player {
55 | string name = 1;
56 | int64 score = 2;
57 | int64 coins = 3;
58 | }
59 |
60 | message Record {
61 | google.protobuf.Timestamp time = 1;
62 | google.protobuf.Duration duration = 2;
63 |
64 | int64 number = 3;
65 | LobbyType lobby = 4;
66 | GameLength length = 5;
67 | GameType type = 6;
68 | Akkas akkas = 7;
69 | Tanyao tanyao = 8;
70 | // Some strange numbers, that are not ascii numbers like '5' or '2'
71 | NumberType number_type = 9;
72 |
73 | repeated Player players = 10;
74 | string id = 11;
75 | bool is_dz = 12;
76 | bool is_champion_lobby = 13;
77 | }
--------------------------------------------------------------------------------
/vendor/github.com/dnovikoff/tempai-core/hand/effective/effective.go:
--------------------------------------------------------------------------------
1 | package effective
2 |
3 | import (
4 | "sort"
5 |
6 | "github.com/dnovikoff/tempai-core/compact"
7 | "github.com/dnovikoff/tempai-core/hand/calc"
8 | "github.com/dnovikoff/tempai-core/hand/shanten"
9 | "github.com/dnovikoff/tempai-core/tile"
10 | )
11 |
12 | type Results map[tile.Tile]shanten.Results
13 |
14 | type Result struct {
15 | Tile tile.Tile
16 | Shanten shanten.Results
17 | sortId sSortId
18 | }
19 |
20 | func Calculate(closed compact.Instances, options ...calc.Option) Results {
21 | results := make(Results, len(closed))
22 | cp := closed.Clone()
23 | last := tile.TileNull
24 | options = append(options, shanten.StartMelds(closed))
25 | for _, i := range cp.Instances() {
26 | if i.Tile() == last {
27 | continue
28 | }
29 | last = i.Tile()
30 | cp.Remove(i)
31 | results[last] = shanten.Calculate(cp, options...)
32 | cp.CopyFrom(closed)
33 | }
34 | return results
35 | }
36 |
37 | //wd98765
38 | func tilePriority(t tile.Tile) int {
39 | if compact.Honor.Check(t) {
40 | return 0
41 | }
42 |
43 | switch t.Number() {
44 | case 1, 9:
45 | return 1
46 | case 2, 8:
47 | return 2
48 | case 3, 7:
49 | return 3
50 | case 4, 6:
51 | return 5
52 | case 5:
53 | return 6
54 | }
55 | // Unreachable
56 | return 7
57 | }
58 |
59 | func (r Results) Sorted(used compact.Instances) ResultsSorted {
60 | ret := make(ResultsSorted, 0, len(r))
61 | uq := used.UniqueTiles().Invert()
62 | for k, v := range r {
63 | t := (uq & v.Total.Improves).Count()
64 | u := used.CountFree(v.Total.Improves)
65 | id := newSortId(u, t, v.Total.Value)
66 | ret = append(ret, &Result{
67 | Tile: k,
68 | Shanten: v,
69 | sortId: id,
70 | })
71 | }
72 |
73 | sort.Sort(ret)
74 | return ret
75 | }
76 |
--------------------------------------------------------------------------------
/tools/tentool/README.md:
--------------------------------------------------------------------------------
1 | ## Tenhou stats and log downloader
2 | Download stat files and log files to work with them on your local computer.
3 |
4 | Download tool by typing:
5 | ```
6 | go get github.com/dnovikoff/tenhou/tools/tentool
7 | ```
8 |
9 | Initialize the stats repo in current working dir.
10 | ```
11 | tentool stats init
12 | ```
13 |
14 | I suggest that you first download some archives from my [Yandex.Disk](https://yadi.sk/d/uOv87aVsd-l-3A).
15 | The files will be downloaded to `./tenhou/stats` folder.
16 | That could you reduce you downloading time.
17 | Do this by typing:
18 | ```
19 | tentool stats yadisk
20 | ```
21 |
22 | Download stat files from tenhou.net.
23 | The files will be downloaded to `./tenhou/stats` folder.
24 | Repeat this action when you need to get updates.
25 | ```
26 | tentool stats download
27 | ```
28 |
29 | Initialize the logs repo in current working dir.
30 | ```
31 | tentool logs init
32 | ```
33 |
34 | I suggest that you first download some prebuild zip files with logs from my [Yandex.Disk](https://yadi.sk/d/FIIkaucSNjR3Kw).
35 | That would be sure times faster, than downloading all logs from tenhou one by one.
36 | The files will be downloaded to `./tenhou/logs` folder.
37 | ```
38 | tentool logs yadisk
39 | ```
40 |
41 | Collect all log ids from stat files by typing.
42 | Repeat this action, after next call of `tentool stats download`.
43 | ```
44 | tentool logs update
45 | ```
46 |
47 | Download log files from collected log ids by typing
48 | ```
49 | tentool logs download
50 | ```
51 |
52 | Alternatevly you can init with makefile
53 | ```
54 | make init
55 | ```
56 |
57 | And update with
58 | ```
59 | make download
60 | ```
61 |
62 | Now you have full database of phoenix logs on your machine.
63 | Consider reading `tentool stats --help` and `tentool logs --help` on more commands and flags.
--------------------------------------------------------------------------------