[GO] Grundlegende Richtlinie für die Suche nach Mahjong

Ergänzung, die schlau ist, einmal zu schreiben

Vielleicht gefällt es mir doch. Koyus. Nostalgisch C. "[Mahjong macht Spaß](https://www.google.co.jp/search?q=%E9%BA%BB%E9%9B%80%E3%81%A3%E3%81%A6% E6% A5% BD% E3% 81% 97% E3% 81% 84% E3% 82% 88% E3% 81% AD & source = lnms & tbm = isch & sa = X) "(Saki) und Yuka, die Herausforderung bei der Implementierung eines Mahjong-Spiels Es ist interessant, weil bei der Wartesuche so viele Dinge gesagt werden können, was dem mittleren Schwierigkeitsgrad entspricht. Die vorherige Geschichte von Rimu und die Geschichte der Zustandsmaschine sind von geringem Schwierigkeitsgrad, und die KI von NPC ist von hohem Schwierigkeitsgrad (nun, so dass sich die Anzahl der Hörer verbessern wird). Es ist schwer zu treffen, aber es ist relativ stark, aber es ist nicht menschlich, daher ist es schwierig zu berechnen, was für eine menschenähnliche und starke KI ist. Shi. Da es keinen ausführlichen Kommentar zu Computer Mahjong gibt (es scheint ein Muster zu sein, das nicht herauskam, weil es nicht verkauft wurde, obwohl es herauskam), ist es außerdem eine Schatzkammer an Material. Wenn Sie es sorgfältig machen, wird es ein Buch bis zur Anzahl der Hörversuche sein, und es wird ein ziemlich robustes Buch sein. (Das Folgende ist nicht höflich, deshalb weiß ich nicht: Ich habe das Gefühl, ich sage nur die Antwort)

Datenformular

Es gibt verschiedene Möglichkeiten, Mahjong-Kunsthandwerk auszudrücken.

/*(1)So fügen Sie jeden Kacheltyp in ein Array ein*/
   t_pai pai[14];
   int painum;
/*(2)So legen Sie die Anzahl der Besitztümer für jeden Kacheltyp in einem Array fest*/
   int painum[9+9+9+3+4+1];/*Enthält ein Dummy-Element*/
   int pairednum[4];/*Speichert nur die Anzahl der roten Kacheln, die sich mit Painum überlappen (1 Dummy ist enthalten)*/
/*(3)Gibt es eine Möglichkeit, damit wie mit einer Holzkonstruktion umzugehen? Ich bin nicht sicher, aber ich bin sicher, dass es ineffizient ist*/
   t_pai_node top;
   top.same(), top.more(), top.less(), //Und? Kurz gesagt, ich wollte oben ohne sagen.

(1) eignet sich für die Handhabung im Anzeigesystem und den Nachahmungsfluss. Wie Sie jedoch sehen können, wenn Sie diesen Artikel bis zum Ende lesen, ist (2) für Analysen wie die Suche nach Mahjong-Warten schneller. Selbst wenn (1) so bleibt, wie es ist, denke ich, dass es schneller gemacht werden kann, als wenn Sie es auf intelligente Weise tun, aber da Sie beißen und Schritt für Schritt scannen müssen, wird der Code kompliziert. Eine effiziente Auflistung der Gewinner-Kandidatenplättchen ist schwierig, und die Gesichtszerlegung erfordert wiederholte Austausche und Sortierungen. Da die Anzahl der Elemente jedoch gering ist, ist dies der einzige Vorteil, aber es ist unvermeidlich, dass der TRY tief ist und der Algorithmus schwer in die Pipeline zu bekommen ist, sodass (2) gewinnt. Ich werde den Einwand prüfen. Und ich habe das Gefühl, dass eine Menge Mahjong-Software das tut.

Da es einfach ist, (1) bis (2) zu generieren, ist es angebracht, es in (1) zu verwalten, außer wenn das Erscheinungsbild analysiert wird, und grob (2) zu generieren, wenn das Erscheinungsbild analysiert wird. Überlegen. Der Grund, warum der Dummy in (2) vorbereitet wird, besteht darin, (1) → (2) ohne Verzweigungssprung auszuführen, selbst wenn die Anzahl der Töne gering ist. Mit anderen Worten, das letzte Element ist die Anzahl der Nullkacheln.

Es kann auch Painum [12 + 12 + 12 + 12 + 1] für eine andere Optimierung sein. Wir werden später darüber sprechen.

Das Quietschen wird hier nicht erwähnt, sollte aber separat behandelt werden. Reflektieren Sie nur im primären Array (Gravur- / Bestelldaten), um die Kombination im Voraus zu gewinnen.

Im Folgenden werde ich unter der Voraussetzung des Datenformats von (2) schreiben.

Nachdruck von Kommentaren an einem bestimmten Ort

Es gibt zwei Hauptrichtlinien für die Suche nach Mahjong.

A [Es hat Potenzial, aber es ist in der Regel kompliziert, die Warteliste zu identifizieren]
versuchen Sie es mit einem einzelnen Pferd (1 bis 3 eigene Kacheln)
Entfernen Sie die Gravur und Junko von beiden Enden, wobei die Gravur Vorrang hat. Wenn Sie sie entfernen können, können Sie auf ein einzelnes Pferd warten
versuche Jakuto bestätigt (2-4 Besitzplättchen)
Entfernen Sie die Gravur und Junko von beiden Enden, wobei die Gravur Vorrang hat. Wenn ein Überschuss vorliegt, handelt es sich um eine Warteform
Finden Sie ein abgeleitetes Formular, indem Sie das letzte verbleibende Warteformular bei den Männern unterbringen, die es oben entfernt haben
Wenn der letzte Wert 45 ist, interagieren Sie mit dem entfernten Junko, der 3 oder 6 enthält.
Wenn beispielsweise 678 vorhanden ist, lesen Sie als (45/678) → (456/78).
Weiter von 78 der gleiche Satz unten
Wenn beispielsweise 234 vorhanden ist, lesen Sie (45 ・ 234) → (345 ・ 24).
Wenn 66 beispielsweise ein Spatzenkopf ist, sollte er als (45.66) → (456/6) gelesen werden und auf ein einzelnes Pferd warten.
Wenn es beispielsweise 666 gibt, lesen Sie (45/666) → (456/66) als Warten auf einen Shabo mit dem Spatzenkopf.
Wie Sie sich vorstellen können, suchen Sie, um keine Schleife zu erstellen
Entfernen Sie die 4-Karten-Wartebox aus der Wartebox

B [Es erfordert viel Arbeit, das Warteformular zu identifizieren, aber es ist schnell, wenn Sie nur das Warteformular finden]
Versuchen Sie, die eigenen Kacheln und die Kacheln davor und danach hinzuzufügen
versuchen Sie Jakuto bestätigt (2-4 hinzugefügte Ergebnisse sind im Besitz)
Entfernen Sie die Gravur und Junko von beiden Enden, wobei die Gravur Vorrang hat, und es ist in Ordnung, wenn sie entfernt werden kann

B'[Spezifischer Aufwand des oben genannten Warteformulars]
Das hinzugefügte Plättchen ist im Spatzenkopf enthalten → Einzelpferd
Die hinzugefügten Kacheln sind in Junko enthalten → Je nachdem, wie sie enthalten sind, Seitenspannung, Passform und beide Seiten
Die hinzugefügte Kachel ist in der Gravur → Shabo enthalten
Wenn es sich um einen Dreifachgravurtyp handelt, wird auch ein Wartetyp hinzugefügt, wenn er als Junko gelesen wird
Das Obige kann mehrfach interpretiert werden → Die Interpretation mit der höchsten Punktzahl sollte durch Berechnung der Note und Beurteilung der Kombination erfolgen.
→ Die Tsumo-Markierung ändert sich je nach Warteform, sodass mindestens die Tsumo-Flagge sichtbar sein muss.
→ Wenn Sie die Punktzahl festlegen, können Sie den Selbstwind, den Feldwind, den Reichweitenzustand, die Dora usw. sehen.
→ Dies gilt auch für A. Es ist schwer, es ordentlich zu modularisieren
Die meisten Spieldaten müssen hier sichtbar sein

B ist glatt, um das Warten zu identifizieren und die Rolle zu beurteilen. Die Berechnung der Entfernung einschließlich der Anzahl der Zuhörer und der Wahrscheinlichkeit für die Gewinnform ist eine Erweiterung von A, sodass in vielen Fällen beide implementiert werden. Wenn Sie das Warteformular nicht in B angeben und dann die Unterscheidung zwischen Tsumo und Izukuri mit einem Flag für jedes Warteformular übergeben, können Sie das Tsumori 3-Impressum oder das Pinf-Urteil nicht beurteilen. Ich habe einen Fehler gemacht. Wie ich in den Kommentaren geschrieben habe, ist diese Art der Verarbeitung sehr ärgerlich, wenn Sie nicht alle Spieldaten vervollständigen können (ehrlich gesagt müssen Sie fast alles außer dem Fluss passieren).

Und es ist Optimierung!

Der Punkt ist also, wie man dies mit dem minimalen Sprung schreibt und nur den Speicher verwendet, der in den L1-Cache passt. Wenn Sie jedoch einen Mahjong-Spieleserver schreiben, erfolgt der größte Teil der Verarbeitung in Form eines Schwertes. Da Sie eine Analyse durchführen, können Sie umso mehr Personen aufnehmen, je schneller dieser Typ ist. Die Zustandsmaschine ist nur mühsam mit so kleinen Regeln wie einer Kombination aus Quietschen und Quietschen, Dublonen, dunklen Dosen und Chankans umzugehen (obwohl es sehr mühsam ist, die Regeln variabel zu machen). Es ist (sicherlich) nicht so, als würde man Verarbeitungszeit in Anspruch nehmen. Ich denke, die Lobby und der Spielfluss können mit Node.js + react.js + socket.io verwaltet werden. Nur die Erscheinungsanalyse kann jedoch C10K ohne Low-Level-Codierung mit C ++ - Bindung nicht unterstützen.

Die Anzahl der Listenings wird um höchstens 1 pro Tsumo reduziert. Wenn Sie also die Anzahl der Listenings richtig berechnen können, können Sie das Erscheinungsbild auf dem Server alle paar Runden einmal analysieren. (Listen-1) Sie können die Erscheinungsanalyse für die Tour überspringen. Und dies ist der Wurzelschnitt und der effektivste. Auf dieser Grundlage werden wir das Abschlussurteil, das Hörurteil, das Erreichbarkeitsurteil usw. weiter optimieren, einschließlich der Berechnung der Anzahl der Hörer. Darüber hinaus muss die Anzahl der Anhörungen auf drei Arten berechnet werden: sieben Paare, Kokushi und Face-to-Face. Die Anzahl der Anhörungen von Angesicht zu Angesicht erfordert jedoch einen Schnitt, der über die hier erläuterten hinausgeht. Dies liegt daran, dass die Anzahl der Hörversuche aus der Kombination von Toko, Paar und Gesicht berechnet werden kann, die Unterteilung jedoch unerwartet mehrdeutig ist. Wenn Sie dies schlecht machen, können Sie in eine tiefe Suche geraten. Es ist ärgerlich, den falschen Wert zu erhalten. Wenn ich Lust dazu habe, werde ich es bald schreiben, aber ich werde mit den Grundlagen beginnen.

  a[0]>=Wenn 3
 [ a[0], a[1], a[2] ] = [ a[0]-3, a[1], a[2] ] /*Versuchen Sie, die Gravur von der Kante zu nehmen*/
Andernfalls
 st = min(a[0],a[1],a[2])Wann
 [ a[0], a[1], a[2] ] = [ a[0]-st, a[1]-st, a[2]-st ] /*Versuchen Sie, Junko vom Rand zu nehmen*/

/*Natürlich danach
a[1], a[2], a[3]
a[2], a[3], a[4]
a[3], a[4], a[5]
a[4], a[5], a[6]
a[5], a[6], a[7]
a[6], a[7], a[8]
Auf jeden von ihnen wird der gleiche Prozess angewendet.
Die Gravur ist
a[7]
a[8]
Der gleiche Prozess wird angewendet.
Wenn Sie die Zeichenverarbeitung mit der später beschriebenen Speicherzuordnung durchführen möchten
a[9]
Erfordert auch Gravur.
*/

Es ist nur erforderlich, die Berechnung durch Kombinieren von Bitoperationen und Tabellenreferenzen ohne Verzweigung durchzuführen und aufzuzeichnen, was geschlossen wurde. Nun, die Antwort lautet in den meisten Fällen "Subtrahieren Sie 0 für das, was Sie wollen, ohne Auswirkungen". Schreiben Sie dann vorerst den Datensatz des Ergebnisses und setzen Sie das Inkrement auf die Zeigeradresse nur dann auf 1, wenn Sie den Datensatz behalten möchten, und fügen Sie zu anderen Zeiten 0 zur Zeigeradresse hinzu, und es wird schließlich überschrieben. Schließlich wird es ignoriert.

Das Folgende ist eine einfache Korrektur des obigen Anfangs ohne zu springen.

sample


if(a[0] >= 3)
{
    a[0] -= 3;
    *result++ = pai_1pin_ko;
}
//  ↓
int kotsu[] = {0,0,0,3,3};
*result = pai_1pin_ko;
result += kotsu[a[0]]>>1;
a[0] -= kotsu[a[0]];

Es fühlt sich an wie. Als ich es zum ersten Mal in logischer Operation schrieb, habe ich einen Fehler gemacht, also wurde ich wütend und schrieb es in eine Tabellenreferenz um. Es ist schnell genug, da ein Array dieser Größe niemals aus dem Cache herauskommen kann. Vielleicht schneller als logische Operation.

Übrigens hinzugefügt

Der obige gewinnt die Tabellenreferenz. Kleine Tabellenreferenzen sind so schnell wie dumm. Min hat jedoch eine berühmte arithmetische Methode, und die logische Operation gewinnt. Dies ist das. Diese 31-Bit-Rechtsverschiebung ist ein Standard für Dinge wie einen ternären Operator, der Operationen verwendet, die in positive und negative unterteilt sind. Es kommt sehr oft heraus, um Sprünge zu eliminieren.

sample


st = min(a[0], a[1], a[2]);
    /*↓*/
/*Dies ist eine Bitoperation. Berühmter Typ*/
int ab = a[0] + (((a[1]-a[0])>>31) & (a[1]-a[0]));
int st = ab + (((a[2]-ab)>>31) & (a[2]-ab));
assert((0x80000000>>31)==(-1));

Wenn Sie beispielsweise eine positive Zahlenprüfung durchführen, führen Sie beispielsweise ((-a) >> 31) aus. Da es von der Umgebung abhängt, habe ich auch eine Bestätigung veröffentlicht, um zu beurteilen, ob es funktioniert. In Bezug auf die Anwendung in Mahjong, wenn Sie die besessenen Kacheln sagen, wenn Sie die Gewinnerkandidatenkacheln und die Kacheln davor und danach auflisten,

p[0]=a[1]*a[2],p[1]=a[2]*a[3]..., 
q[1]=a[2]*a[0],q[2]=a[3]*a[1]..., 
r[2]=a[0]*a[1],r[3]=a[1]*a[2]..., 
p[0]+=q[0]+r[0]+a[0],p[1]+=q[1]+r[1]+a[1]...
p[0]=((-p[0])>>31),p[1]=((-p[1])>>31)...

Anschließend können Sie die Kachel ungleich Null als Kandidaten auswählen.

Im obigen Code sind die Puffer für a, p, q und r nur aus Gründen der Klarheit und Schönheit geschrieben, und in Wirklichkeit sind nur zwei Puffer erforderlich, die Originaldaten a und das Ergebnis, das p enthält.

Übrigens, obwohl es sich um die vorderen und hinteren Kacheln handelt, wenn es nur 3 Zylinder gibt und es keine 4 Zylinder oder 1 Zylinder gibt, wenn man überlegt, ob 2 Zylinder ein Gewinnerkandidat sein können, wenn 2 Zylinder nicht in der Handkachel sind Sie können kein Gewinner sein, oder? Deshalb schaue ich die beiden nebeneinander an.

Hier kommen Multiplikation und Addition heraus, aber die Größe des Wertes hat keine Bedeutung. 0 × 0 = 0,0 × positive Zahl = 0, positive Zahl × 0 = 0, positive Zahl × positive Zahl = positive Zahl, dann 0 + 0 = 0,0 + positive Zahl = positive Zahl, positive Zahl +0 = Es wird als eine Art logisches Produkt / Summe von positiven Zahlen, positiven Zahlen + positiven Zahlen = positiven Zahlen verwendet. Auch in diesem Fall erscheinen 7 Paare derselben Formel in p und r. Bauen Sie sie also so zusammen, dass sie gut verwendet werden können. Sie können es dem Compiler überlassen.

Übrigens, wenn Sie eine Junior High School-ähnliche Optimierung durchführen. Dies ist eine einfache Formeltransformation.

p[2] = (a[0]+a[3])*(a[1]+a[4])-a[0]*a[4]+a[2];

Der Berechnungsbetrag selbst ist das ursprüngliche p [2] = a [0] * a [1] + a [1] * a [3] + a [3] * a [4] + a [2]; Es ist das gleiche wie, aber es gibt auch eine böse Methode, um hier anhand des Fortschritts der Berechnung zu berechnen, die als "Muskelmod 3" bezeichnet wird und später veröffentlicht wird. Es ist effektiver, den Speicherzugriff im L1-Cache beizubehalten, Sprünge zu reduzieren und die Pipeline auszuführen, als dies so weit zu tun. Es ist so lecker, dass es lesbar ist. Es gibt eine Szene, in der dieser Prozess nahe an "Muscle Mod 3" liegt.

Es kann eine gute Idee sein, die Kacheln, die bereits mit 4 Karten verwendet wurden, aus der Betrachtung zu entfernen, da die Verwendung von 4 Karten sehr selten ist. Daher kann es eine gute Idee sein, die Gewinnerplättchen zu identifizieren und sie später zu entfernen. Es gab eine Geschichte, die mich ein wenig zum Lachen brachte, als ich 4 Karten benutzte, und ich erinnere mich, dass es einen Fehlerbericht gab, dass "1111234444" nach dem Stream als No-Ten behandelt wurde. Nein, es ist ein Hit, es ist nicht in der Welt. Die Geschichte geht schief, aber es gibt eine ähnliche Geschichte in der Novetenform, mit 3 Furo, "3456", "3" aus der oberen Familie, Option "Ron", aber "Chi" nicht. Oder so. Sie können nicht singen, da der Ersatz bestätigt ist.

Und zurück zur Geschichte: Wenn Sie beurteilen möchten, ob Sie daraus eine Speerspitze machen können, dann ist es ((2-a) >> 31). Es ist nicht immer so, dass man so ehrlich urteilen kann ... Nächster!

Große Fähigkeit "farbcodierter Mod 3"

Übrigens gibt es höchstens 34 Arten der Vorverifizierung der oben genannten Kandidatenkacheln, einschließlich Charakterkacheln. Bei der vorläufigen Überprüfung können höchstens 25 Typen ausprobiert werden, da die Anzahl der Handarbeiten begrenzt ist. Wenn Sie sich entscheiden, nicht zu scannen, wenn Sie nicht zuhören, und mehr als 20 Kandidaten finden, können Sie beschneiden, da absolut nicht zugehört wird. Die Verengung, die eine solche Verengung lächerlich macht, ist jedoch die Verengung durch den folgenden "farbcodierten Mod 3".

Sie können die Anzahl der Gewinnerkacheln nach Farbe eingrenzen, z. B. in welcher Farbe sie sich befinden. Betrachtet man Mod 3 der Anzahl der Kacheln, die für jede Farbe gehalten werden, gibt es zunächst in der Gewinnerform irgendwo einen Spatzenkopf, und alle anderen sind Facetten von jeweils 3, also (2, 0 für andere) Es ist eine Kombination. Das ist definitiv der Fall bei Händen von Angesicht zu Angesicht.

Wenn es um das Hören geht, gibt es zwei Muster, je nachdem, ob Sie eines von 2 oder 0 zeichnen, weil Sie eines von Ihrem Gesicht gezeichnet haben. Mit anderen Worten, Sie können nur zwei Mal (1, 0 für andere) und (2, 2, 0 für andere) hören. Und da die Stelle, an der das Trefferplättchen gezogen wird, ungleich Null ist, besteht die Möglichkeit, dass sich an der Stelle ungleich Null ein Trefferplättchen befindet. Wenn nach Muster geordnet, wenn (1, andere ist 0), hat der Spatzenkopf die gleiche Farbe wie das Gewinnerplättchen, und wenn (2, 2, andere ist 0), haben der Spatzenkopf und das Gewinnerplättchen unterschiedliche Farben. Zu diesem Zeitpunkt werden die Kandidaten für den Sieg und der Kopf des Spatzen eingegrenzt.

Es ist nicht sehr sinnvoll, Sprünge während dieser Eingrenzung zu unterdrücken (obwohl es besser ist, die Tabelle gut zu verwenden). Verwenden Sie sie daher, wenn Sie das Muster richtig teilen. Zum Zeitpunkt 1 ist es notwendig, "Versuch pro Schwert" x "Versuch Speerspitzenkandidat" durchzuführen, aber zum Zeitpunkt 2, 2 führt einer "Versuch Speerspitzenkandidat" + der andere "Versuch pro Speer" durch. Wenn Sie einen darauf spezialisierten Beurteilungscode schreiben, können Sie ihn daher weiter optimieren. (Ersteres wird als Produktsuche und letzteres als Summensuche bezeichnet.)

Basierend auf dem Ergebnis dieser Beurteilung können Sie den Startzeiger ersetzen und ausführen, aber nur einen Punkt. Lassen Sie uns den Überprüfungsprozess für verschiedene Farben verschachteln und die Pipeline optimal nutzen. Dann ** weiß der Compiler nicht, dass sich der Bereich der Zeiger, die auf jede Farbe zeigen, nicht überlappt **. Also ** müssen Sie manuell verschachteln **. Es befindet sich jedoch in einem Zustand wie ein Urteil mit gemischten Farben und guten Bedingungen. Wenn Sie also den Mut haben, können Sie superschnell schreiben. Diese Mod-3-Methode ist eine der Grundideen, die beim Beschneiden in anderen Kachelanalysen häufig vorkommen (z. B. bei der Berechnung der Höranzahl).

Übrigens ist es in Ordnung, die Erreichbarkeit durch Verwerfen nacheinander zu beurteilen (insbesondere, wenn die Richtlinie auf der Clientseite berechnet werden soll), aber aus Sicherheitsgründen wird sie bisher auf der Serverseite beurteilt. Wenn Sie den Client benachrichtigen möchten, ist die Schleife "Versuch zu verwerfen, versuchen Sie, eine Kandidatenkachel zu gewinnen" unerwartet tief, sodass Sie sie optimieren möchten. Wenn Sie NPCs auf einer angemessenen Anzahl von Servern ausführen, ist dies unbedingt erforderlich.

In der Erreichbarkeitsbeurteilung, dh der Hörbeurteilung im Zustand von 14 Blättern, ist "mod 3 nach Farbe" (2, andere sind 0), (1,1, andere sind 0), (1,2,2, andere sind Es gibt nur 3 Möglichkeiten von 0). Und Sie haben bereits die Farben der Kandidaten für jedes Muster identifiziert, oder? Wenn es 1 gibt, ist die Farbe von 1 ein Kandidat für das Verwerfen, andernfalls ist die Farbe von 0,2 ein Kandidat für das Verwerfen. Wenn Sie weiter darüber nachdenken, kann die Farbe der weggeworfenen Kacheln weiter eingeschränkt werden. Wenn wir "vollständige Gesichtszerlegung" "Tris" nennen, Wenn 1,1, Die Bedingung ist, dass "eine 1 bei der Produktsuche erfolgreich ist, eine andere 1 Tris ist, indem eine geschnitten wird, und andere Farben ebenfalls Tris sind". Ähnlich Wenn 1,2,2 "2, 2 gelang die Summensuche, nur 1 ist Tris durch Schneiden eines Stückes, andere Farben sind ebenfalls Tris", Wenn 2, a "2 schneidet ein Blatt und ist erfolgreich in der Produktsuche, 0 ist alles Tris" b "2 ist Tris mit Warten, 0 ist Tris mit Spatzenkopf, andere Farben sind Tris" c "2 ist Tris mit Spatzenkopf, einige 0 ist Tris mit Warten und andere Farben sind Tris" Es wird sein. Es scheint schwierig zu sein, aber wenn ich den Code schreibe, fühlt es sich gut an, immer mehr einzugrenzen. Da es sich um "Jakuto Tris" - "Machi-Mai Tris" handelt, können Sie im Machi-Mai Tris-Urteil sofort überprüfen, zu welcher Kategorie es gehört. (Das heißt, es gibt drei Arten von Ausgaben: Waiting Tris und Sparrow Head Tris, Non-Waiting Tris und Sparrow Head Tris, die beide fehlschlagen: Siehe auch "Muscle Mod 3" unten) Und Friten vom Ende Wenn die Möglichkeit der Reichweite zuerst beurteilt und anders behandelt wird, wird der Fall von 2 etwas weiter eingegrenzt, und wenn alle Nullen Tris sind, gehört er immer zu einer, wenn es sich nicht um eine Gewinnform handelt. In anderen Fällen gibt es also immer eine 0, deren Tris-Beurteilung NG ist (wenn es zwei oder mehr gibt, ist es nicht zehn), und b und c können durch Festlegen der Farbe gleichzeitig beurteilt werden. ist. Daher wurden die Fälle, in denen das "wartende Tris-Urteil", das dem "Versuch, einen Kandidaten zu gewinnen" entspricht, durchgeführt werden muss, extrem eingegrenzt. Höchstens zweimal.

Wenn Sie dann suchen, indem Sie für jede Kombination von Mustern "vollständige Gesichtszerlegung von Farbe A und Summensuche von Farben B und C" mischen, können Sie einen Code schreiben, der leicht in die Pipeline zu bekommen ist. Hier ist es notwendig, zu entwerfen, um nicht die Reihenfolge des Zeichens 牌 zu beurteilen, sondern 12 Elemente für jedes Mantsutsu-Linienzeichen zu erstellen 1 2 3 4 5 6 7 8 9 ◆◆◆  ①②③④⑤⑥⑦⑧⑨◆◆◆  123456789◆◆◆ Südosten ◇ Nordwesten ◇ Von Weiß ◇ Mitte ◆◆ Es ist auch eine gute Idee, es so in den Speicher zu stellen. Es ist in Ordnung, wenn Sie die Gravursuche bis zu [9] durchführen und ◇ nach Berechnung des Gewinnerkandidaten mit 0 überschreiben. Der Vorteil, ausnahmslos Hochgeschwindigkeitsalgorithmen wie Tris-Urteil und Produktsuche verwenden zu können, sollte den Verlust überwiegen, der zu einer verschwenderischen Verarbeitung führt. Bis zu diesem Punkt sind 10 Elemente in Ordnung, aber wenn Sie "Muscle Mod 3" im nächsten Abschnitt mit Verzweigungsunterdrückung verwenden möchten, müssen Sie 12 Elemente verwenden. Nun, es erhöht sowieso nicht den Rechenaufwand und ich denke, es ist in Ordnung, ihn durch Berühren zu sichern, wenn man die Summe von "Muskelmod 3" berechnet.

Sie können sogar "Muscle Mod 3" verwenden

Ich habe es hier umgeschrieben. Sehen Sie sich nicht den Bearbeitungsverlauf an. Ich habe Angst (danach). Die Situation unterscheidet sich geringfügig von der von "farbcodiert", daher ist sie kompliziert. Werfen wir also einen zweiten Blick und gehen höflich.

Was ist "Muscle Mod 3"?

int suji[3];
suji[0] = (a[0]+a[3]+a[6]) mod 3;
suji[1] = (a[1]+a[4]+a[7]) mod 3;
suji[2] = (a[2]+a[5]+a[6]) mod 3;

Und wenn Sie es als s (suji [0], suji [1], suji [2]) usw. abkürzen, wo auch immer die Gravur ist, s (0,0,0), wo ist Junko? Ist auch s (1,1,1), also wenn Tris passt, ist es immer s (a, a, a). Ist es soweit in Ordnung?

Wenn es sich also um ein 13-Blatt-System (n * 3 + 1) handelt, sollte es sich zu paisum mod 3 == 1 addieren, sodass es immer in der Form von s (a, a, a + 1) in keiner bestimmten Reihenfolge vorliegt. Das Entfernen des Spatzenkopfes bedeutet das Entfernen derselben zwei Kacheln, also s (-2,0,0) = s (+ 1,0,0), und die Annahme, dass eine Tsumo-Kachel auch s (1,0) ist , 0). (Welche Quelle ist noch unentschlossen)

Da s (a, a, a + 1) dupliziert werden kann, um 1 zu zwei Stellen zu addieren, um s (a ', a', a ') zu machen,

Entweder s (a ** + 1 **, a ** + 1 **, a + 1) oder s (a, a, a + 1 ** + 1 + 1 **).

OK. Jetzt können Sie es für die Produktsuche verwenden. Angenommen, ein Spatzenkopf bei a + 1 von s (a, a, a + 1) befindet sich das wartende Plättchen ebenfalls in derselben Zeile (selbst wenn sich nur eines auf dem Handplättchen befindet, ist der Sperlingskopf TRY erforderlich). .. Und wenn Sie einen Spatzenkopf in einem der beiden A annehmen, befinden sich die wartenden Kacheln in unterschiedlichen a-Linien (Sie können den Spatzenkopf in diesem Fall also nur ausprobieren, wenn Sie bereits zwei oder mehr in Ihrer Handplättchen haben).

Wenn Sie also nachverfolgen, auf welche Muskeln Sie beim Aufheben eines Spatzenkopfes warten sollten, werden Sie mit 3 Tris pro Spatzenkopf immer besser. Ich muss es möglich machen, Tris mit einem gebrochenen Spatzenkopf von -1 falsch zu beurteilen, aber höchstens 9 Mal * Tris 3 Mal, durchschnittlich 3-4 Mal x 3 Mal Schleife, also melden Sie sich an Dann können Sie das Produkt beurteilen, indem Sie über den Tisch springen. Die Verzweigungsvorhersage durch Tabellensprung ist in gewissem Maße ebenfalls korrekt. Ist es ungefähr 30%?

Ah, es war erfrischend. Ich habe es nicht wie üblich gesagt, aber es tut mir wirklich leid, das erste zu schreiben.

Obwohl die Geschichte schief geht

Als ich jung war, träumte ich, wenn ich dem Compiler den Eingabedefinitionsbereich als Hinweis geben würde, könnte ich verrückte Optimierungen vornehmen, aber ich habe verschiedene verrückte Optimierungen unter Verwendung des Definitionsbereichs selbst durchgeführt. Als ich es sah, kam ich zu dem Schluss, dass es nicht sehr vielversprechend war, die Maschine das machen zu lassen. Es scheint jedoch, dass es noch mehr CPU-Raten bestimmende Verarbeitung gibt, und wenn man bedenkt, dass die Taktrate nahe der theoretischen Grenze liegt, kann dies eine Lebensweise sein. Da die Verwendung begrenzt sein wird, handelt es sich um eine Erweiterung grundlegender prozeduraler und funktionaler Sprachen wie C bzw. Haskell, für Sprachimplementierer jedoch um das Thema "Optimierung durch Verwendung des Definitionsbereichs". Wie ist das?

Recommended Posts

Grundlegende Richtlinie für die Suche nach Mahjong
FX_tool für Hython Basic02
FX_tool für Hython Basic01
Grundlegende Python-Grammatik für Anfänger
Grundlegende Befehle für Dateivorgänge