Trova la migliore mossa immediata in un gioco "match-3"


11

La tua sfida oggi è quella di prendere input in questo modo:

fbcfbee
ffcabbe
debceec
bccabbe
edcfbcd
daeaafc
eebcbeb

Ed emetti la migliore mossa possibile in un gioco simile a Bejeweled che corrisponderà a tre o più lettere, come questa (nota la maiuscola Be C):

fbcfbee
ffcabbe
deBCeec
bccabbe
edcfbcd
daeaafc
eebcbeb

Specifiche complete:

  • L'input sarà costituito da nrighe di nlettere minuscole ciascuna (dove npotrebbe esserci un numero qualsiasi).
  • L'output sarà la mossa migliore che potresti fare in un gioco match-3, con le due lettere che vuoi scambiare in maiuscolo.
  • Le partite dovrebbero avere la seguente priorità (in questi esempi, .indica un quadrato che non ha importanza):

    1. Cinque in-un-fila

      xxYxx
      ..X..
      
    2. Rotto cinque di fila

      X..
      Yxx
      x..
      x..
      

      o

      .X.
      xYx
      .x.
      .x.
      
    3. Four-in-un-fila

      xYxx
      .X..
      
    4. Tre-in-un-fila

      xYx
      .X.
      

    È necessario trovare la corrispondenza con la massima priorità e produrla.

  • Se sono presenti più corrispondenze con la stessa priorità, è possibile emetterne una qualsiasi.
  • Ci sarà sempre almeno una partita (il tuo programma può interrompersi se non ci sono partite o fare tutto quello che vuoi).
  • L'I / O può essere in qualsiasi formato ragionevole (stdin / out, lettura e scrittura di file, argomenti di funzioni / valori di ritorno, finestre di dialogo, ecc.) Ma NON codificato (come x="[insert input here]").
  • Questo è quindi vince il codice più breve in byte. Se si utilizza l'accesso alla rete per qualche motivo, tutti i byte scaricati dalla rete vengono conteggiati rispetto al punteggio.

1
+1, ma protesto il titolo; potrebbe esserci una mossa migliore. Ad esempio, uno che crea due cinque o uno che provoca una goccia per creare più cose.
Justin il

Copre anche il cinque di fila rotto ..x.\nxxYX\n..x.?
Peter Taylor,

@Peter Sì.
Maniglia della porta

Ci sono 2 spezzati 5 in uno schema a righe: il modello L e il modello T. Hai bisogno che entrambi siano abbinati?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳,

@nhahtdh Sì, lo modificherò per chiarirlo.
Maniglia della porta

Risposte:


2

Python3.4, 772

(Utilizzando le schede per il rientro, anziché gli spazi.)

import sys,itertools as I
B=[]
for l in sys.stdin:
    l=l.rstrip()
    B.append(list(l))
Z=len(B[0])
F=T=None
R=range
N=min
X=max
P=I.product
S=0
def C(I,J,K,L):
    global F,T,S
    if K<0 or K>=Z or L<0 or L>=Z: return
    B[I][J],B[K][L]=B[K][L],B[I][J]
    h=v=1
    m=B[K][L]
    for i in R(K+1,N(Z,K+5)):
        if B[i][L]!=m:break
        v+=1
    for i in R(K-1,X(0,K-5),-1):
        if B[i][L]!=m:break
        v+=1
    for j in R(L+1,N(Z,L+5)):
        if B[K][j]!=m:break
        h+=1
    for j in R(L-1,X(0,L-5),-1):
        if B[K][j]!=m:break
        h+=1
    c=X(h,v)*2
    if N(h,v)>=3:c+=N(h,v)
    if c>S:S=c;F=I,J;T=K,L
    B[I][J],B[K][L]=B[K][L],B[I][J]
for i,j in P(reversed(R(Z)),R(Z)):
    for d,e in (1,0),(0,-1),(0,1),(-1,0):
        C(i,j,i+d,j+e)
for i,j in P(R(Z),R(Z)):
    c=B[i][j]
    if (i,j)in(F,T):c=c.upper()
    print(c,end=('',"\n")[j==Z-1])

Invece di [c for c in l], potresti semplicemente fare list(l).
Maniglia della porta

Usa (i, j) in (F, T) invece di due confronti - 778
Austin Hastings,

F = (i, j) -> F = i, j. Deglobalize 2 r / o syms - 770
Austin Hastings,

Bug risolto: rotto-5 non dovrebbe battere vero-5.
Austin Hastings,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.