Archer

RiichiCity Basics

Notes

Note
  • To use this package, you need to enable 【Auto Settings】-> 【Built-in Mode】.
  • In Riichi City, declaring Riichi is not a standalone action; it is embedded in the discard (a discard with a Riichi declaration), so use the Riichi method.
  • Tile names use the same string representation as Majsoul: 1m-9m (man), 1p-9p (pin), 1s-9s (sou), 1z-7z (honors); red fives are 0m / 0p / 0s.

Package Name

  • actions

Import

  • import "github.com/moxcomic/Archer/internal/platform/actions"

Interface Methods

NameParametersReturn ValueNotes
NewRiichiCityActionsNone*actions.RiichiCityActionsRiichi City interface instance

Instance Methods

NameParametersReturn ValueNotes
Discardtile: string, tsumogiri: boolNoneDiscard a tile, tile is the tile name, tsumogiri indicates if it's the last drawn tile
Riichitile: string, tsumogiri: boolNoneDeclare Riichi (a discard with a Riichi declaration), tile is the discarded tile, tsumogiri as above
ChiicalledTile: string, consumed: []stringNoneChii, calledTile is the called tile, consumed are the two hand tiles forming the run
PoncalledTile: string, consumed: []stringNonePon, calledTile is the called tile, consumed are the two hand tiles used for Pon
DaimingkancalledTile: string, consumed: []stringNoneDaimingkan, calledTile is the called tile, consumed are the three hand tiles
Ankantile: stringNoneAnkan, tile is the tile name
Kakantile: stringNoneKakan, tile is the newly added tile name
TsumoNoneNoneTsumo (Self-draw win)
RonNoneNoneRon (Win by discard)
RyukyokuNoneNoneNine Terminal Tiles (abortive draw)
BabeiNoneNoneExecute Babei
CancelNoneNoneCancel or skip (do not call)

Full Example Script

  • Consistent with Majsoul/Tenhou: in the onExecute callback you receive the AI's recommended result and dispatch by action type to the corresponding RiichiCityActions method.
  • For lq.NotifyAIResult, see NotifyAIResult
  • For GetType, see Action Types
main.go go
package main

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

	"github.com/moxcomic/Archer/internal/platform/actions"
	"github.com/moxcomic/lq"
)

const (
	E_PlayOperation_None           = iota
	E_PlayOperation_Discard        // Discard
	E_PlayOperation_Chi            // Chii
	E_PlayOperation_Pon            // Pon
	E_PlayOperation_Ankan          // Ankan
	E_PlayOperation_Minkan         // Daimingkan
	E_PlayOperation_Kakan          // Kakan
	E_PlayOperation_RiiChi         // Riichi
	E_PlayOperation_Tsumo          // Tsumo
	E_PlayOperation_Ron            // Ron
	E_PlayOperation_JiuZhongJiuPai // Nine Terminal Tiles
	E_PlayOperation_Babei          // Babei
)

func onExecute(result *lq.NotifyAIResult, risk []float64, r, m, f, t float64) {
	if len(result.GetResult()) == 0 {
		return
	}

	onExecuteTarget(result.GetResult()[0], result.GetShanten())
}

func onExecuteTarget(target *lq.AIResult, shanten uint32) {
	action := actions.NewRiichiCityActions()

	// Human-like delay: discard (your own turn, plenty of time) is longer; calls/wins
	// (the server has a response time limit) are shorter to avoid missing the window.
	delay := 250 + rand.Intn(350)
	switch target.GetType() {
	case E_PlayOperation_Discard, E_PlayOperation_RiiChi:
		delay = 700 + rand.Intn(900)
	}
	time.Sleep(time.Millisecond * time.Duration(delay))

	switch target.GetType() {
	case E_PlayOperation_Discard:
		action.Discard(target.GetTile(), target.GetMoqie())
	case E_PlayOperation_RiiChi:
		action.Riichi(target.GetTile(), target.GetMoqie())
	case E_PlayOperation_Chi:
		action.Chii(target.GetTile(), target.GetCombination())
	case E_PlayOperation_Pon:
		action.Pon(target.GetTile(), target.GetCombination())
	case E_PlayOperation_Minkan:
		action.Daimingkan(target.GetTile(), target.GetCombination())
	case E_PlayOperation_Ankan:
		if len(target.GetCombination()) > 0 {
			action.Ankan(target.GetCombination()[0])
		}
	case E_PlayOperation_Kakan:
		action.Kakan(target.GetTile())
	case E_PlayOperation_Tsumo:
		action.Tsumo()
	case E_PlayOperation_Ron:
		action.Ron()
	case E_PlayOperation_JiuZhongJiuPai:
		action.Ryukyoku()
	case E_PlayOperation_Babei:
		action.Babei()
	case E_PlayOperation_None, 321:
		action.Cancel()
	default:
		fmt.Println("RiichiCity: unhandled action type:", target.GetType())
	}
}

Example Code

go
actions.NewRiichiCityActions().Discard("1m", true)