Basitleştirilmiş bir Tamagotchi / Giga Pet yapın!


9

Tamagotchi ve Giga Pets, küçük bir sanal evcil hayvan simüle eden küçük elektronik cihazlardır. Bu evcil hayvanın sağlık, açlık gibi çeşitli istatistikleri vardı.
Son zamanlarda bu örneği yazdım:

import msvcrt,os,sys;d=m=100;h=s=t=p=0;f=10
while 1:
 os.system('cls'if os.name=='nt'else'clear');print("health:",d,"\nhunger:",h,"\nsleep:",s,"\nfood:",f,"\npotions:",p,"\nmoney:",m);t+=1
 if msvcrt.kbhit():
  k=ord(msvcrt.getch())
  if k==102 and h>8 and f:f-=1;h-=9
  if k==115:s=0
  if k==112 and p:p-=1;d+=9
  if k==98 and m>8:m-=9;p+=1
  if k==116 and m>8:m-=9;f+=1
 if t>99:
  t=0;h+=1;s+=1
  if s>80:s=0;h+=9
  if h>80:d-=1
  if d<1:sys.exit(0)
  if d>79:m+=1

Bu 467 baytta çıplak kemikli bir sanal evcil hayvan! Sonra golf profesyonellerinin ne kadar iyi yapabileceğini merak ettim , bu yüzden şimdi meydan okuma.

Meydan okuma

Sanal bir evcil hayvanın 6 istatistikini izleyen ve zaman içinde ve kullanıcı girdisine yanıt olarak bunları güncelleyen bir program yapın. İstatistikler: sağlık ve para (100'den başlayan), yiyecek (10'dan başlayan) ve açlık, uyku ve iksirler (0'dan başlayan).

Program aşağıdaki olaylara yanıt olarak değerleri güncellemelidir:

  • Program girdi almıyorken, düzenli aralıklarla güncelleme yapmalıdır (güncellemeler arasındaki aralık yarım saniyeden kısa veya bir saniyeden uzun olmamalıdır). Her güncelleme aşağıdakileri yapar:

    • Açlık ve Uyku her biri 1 oranında artar.
    • Açlık 80 veya üstü ise Sağlık 1 azalır.
    • Uyku 80 veya üzeriyse, 0'a sıfırlanır ve Açlık ek 9 artar.
    • Sağlık 80 veya üstü ise Para 1 artar.
    • Sağlık 0 ise, programdan çıkılır.
  • Program ayrıca kullanıcı tarafından aşağıdaki tuşlara basıldığında hemen yanıt vermelidir (bu, yalnızca standart girdiden okumak yerine, basılan bir anahtarı algılayıp hemen yanıt verebilecek bir dil özelliği veya kitaplığı kullanmanız gerektiği anlamına gelir) aşağıdaki eylemler:

    • f: Açlık 8'den büyükse ve Gıda sıfır değilse, Gıda 1 azalır ve Açlık 9 azaltılır.
    • s: Uyku 0'a sıfırlanır.
    • p: İksirler sıfırdan büyükse İksirler 1 azaltılır ve Sağlık 9 arttırılır.
    • b: Para 8'den büyükse, Para 9 azalır ve İksirler 1 arttırılır.
    • t: Para 8'den büyükse, Para 9 azalır ve Yemek 1 arttırılır.

İstatistiklerin değerleri her değiştiğinde, formda ekranda görüntülenmeleri gerekir . Bunlardan herhangi biri değiştiğinde, altı istatistik de görüntülenmelidir; ve bir ekrandaki istatistikler virgülle veya satırsonu ile ayrılmalıdır.Stat: value

Bu zorluk normalden sonra geliyor kurallar: yukarıdaki spesifikasyona uyan en kısa program kazanır. (Her zamanki gibi, dil rekabetten daha yeniyse, başvurunun rakipsiz olarak işaretlenmesi gerektiğini unutmayın.)


Başlangıç ​​istatistiklerinin ne olduğunu söylemiyorsanız
Blue

1
Çıktıların "okunması kolay bir şekilde" belirsiz olması gerekir ve bu nedenle "saniyede bir kez ish" olur. Ana
alana

1
Bu nasıl belirsiz? Keşke daha fazla ayrıntı olsaydı, çünkü kendisi belirsiz.
16:53

2
Zaten cevaplar olduğu için Sandbox artık yardımcı olmuyor. Bunu belirsiz olarak işaretleyen insanlar, kendilerini netleştirmek yerine neden belirsiz olduğunu söylemelidir.
16:40

1
@BlueEyedBeast (ve diğer yakın seçmenler) Neyin belirsiz olduğunu merak ediyorum. Orijinal versiyonun bazı önemli sorunları vardı, ancak düzenlemeler bunu düzeltti. En azından, Carcigenicate ve ben için sunumlar sağlayacak kadar açıktı. Belirsiz bulduklarınızla ilgili bazı ayrıntıları paylaşın, böylece ender_scythe geliştirebilir.
Ray

Yanıtlar:


6

C 424 406 386 357 bayt

#define x(a,b,c)if(*#a==C){if(b>8){c-=9;}Z=0;}
L,M=100,H,S=-1,F=10,P,Z,C;t(){H++;S++;L-=H>79;if(S>79)S=0,H+=9;Z=1/L/2;alarm(1);}main(){nodelay(initscr(),L=M);signal(14,t);for(t(H=S);C=getch();Z=Z||printf("\rhealth: %d,hunger: %d,sleep: %d,food: %d,potions: %d,money: %d\n",L,H,S,F,P,M)){x(s,9,S=9;S)x(p,P+8,P--;L+=18;L)x(f,H,F--;H)x(b,M,P++;M)x(t,M,F++;M)}}

Sorun spesifikasyonunda ham girdi ve eşzamansız güncelleme ihtiyacını takdir ediyorum. Bu, ncurses kurulumu ve sinyal işleyicilerinden bazı ek yükler gerektirse de, (umarız) özel golf dillerinden biri tarafından otomatik olarak kazanılmayacakları zaman zaman meydan okumak güzeldir.

Oyunun bittiğinin tam olarak nasıl belirtildiğini belirtmediniz, bu da "Kayan nokta istisnası (çekirdek dökümü)" geleneksel Tamagotchi ölüm çığlığı ile yok oluyor.

Ungolfed

/* Playing a bit fast and loose with the prototyping rules by omitting these;
 * none of the functions I'm using from them *exactly* match the default
 * prototype of `int f();`
 */
//#include <curses.h>
//#include <stdio.h>
//#include <signal.h>
//#include <unistd.h>

#define x(a,b,c)if(*#a==C){if(b>8){c-=9;}Z=0;}
L,M=100,H,S=-1,F=10,P,Z,C;

t() {
    H++;
    S++;
    L-=H>79;
    if(S>79)S=0,H+=9;
    Z=1/L/2;//0 if L>0. otherwise the pet dies of a floating point error
    alarm(1);
}

main(){
    nodelay(initscr(),L=M);
    signal(14,t);
    for(t(H=S); C=getch(); Z=Z||printf("\rhealth: %d,hunger: %d,sleep: %d,food: %d,potions: %d,money: %d\n",L,H,S,F,P,M)){
        x(s,9,S=9;S)
        x(p,P+8,P--;L+=18;L)
        x(f,H,F--;H)
        x(b,M,P++;M)
        x(t,M,F++;M)
    }
}

2

PHP, 396 413 bayt

(Dang, bayt sayısında düzenlemek zorunda olduğum ilk kod golf girişim. Gerçekten amaçlandığı gibi kurallara uymadığı için sleep () çağrısını kaldırmak için düzenlendi.)

Engellemeyen STDIN için bir unix-ish işletim sistemi gerektirir. Garip bir şekilde, daha kısa bir kaynak kodu üretiyorsa / anahtarına karşı anahtar / kasa kullanmak, ancak sonraki sıkıştırılmış sürüm daha uzundu.

<?eval(gzinflate(base64_decode('bY5BT8MwDIXv/Ao0WWujtVJ7YmtITwiNAwhp3KutOE20pImWVGxa999J1IEAcbH87O892wlUqsEjtmnivD/d5rLd9qZPCHX+gFvdOPTNTpl2L/su3bw9PL1kBaEwMHAMLCsocFaGKhjo0BT0Q0iFaUnO4JmXGlPyPZI8TWHPeIe+nbIIGccJqsGTXbi4p4EKEEt4Qs6xH+rlfA6c5DnwEYacregFlcMvziUk/FLQnzN79drosiOIxV/X7kroeklAh9BxsQD7m/H/MXxi4iKoob5bxRuCTtpFHd8Jn8ab0S7iLOz0pO5LgkfpQ0wrzGyNW+VFBSJ7Nj2eKtDZozHvFfBsPfQdHioYso1CtBW47NV4aXpXgb2Z0csn')));

Ungolfed:

<?
shell_exec('stty -icanon');
stream_set_blocking(STDIN, 0);
$u = $s = $p =0;
$f = 10;
$h = $m = 100;
while(1) {
    $t=time();
    while(1)
        if (($k = fgetc(STDIN)) || time() > $t)
            break;
    if ($k == 'f'){
        if ($u > 8 && $f) --$f | $u -= 9;
    } elseif ($k == 's')
        $s = 0;
    elseif ($k == 'p') {
        if ($p) --$p | $h += 9;
    } elseif ($k == 'b') {
        if ($m > 8) $m -= 9 | ++$p;
    } elseif ($k == 't') {
        if ($m > 8) $m -= 9 | ++$f;
    } else {
        if (++$u > 79) --$h;
        if (++$s > 79) $s = 0 | $u += 9;
        if ($h > 79) ++$m;
        if ($h < 1) exit;
    }
    echo"Health:$h,Money:$m,Food:$f,Hunger:$u,Sleep:$s,Potions:$p\n";
}

Bu, "kullanıcı tarafından aşağıdaki tuşlara basıldığında hemen yanıt vermez". sleep(1)Girdiyi işlemeden önce geri dönüş çağrısı bekler . Bir sonraki güncellemeyi yapmadan önce kuyruğa alınmış komutları işlemesine rağmen, bu iyi olabilir.
Ray

Evet, kaydetti. İfadeler büyük bir belirsizdi, bu yüzden yorum konusunda biraz özgürlük aldım çünkü bu şekilde daha kısaydı. :) Bugün zamanım varsa, alternatif çözümü zamanlanmış bir döngü ile kodlayacağım ve her ikisini de dikkate almak için sunacağım.
Alex Howansky

2

Mathematica, 374 bayt

h=m=100;f=10;g=s=p=0;RunScheduledTask[g++;s++;If[g>79,h--];If[s>79,s=0;g+=9];If[h>79,m++];If[h<1,Quit[]]];Dynamic@Row[{EventHandler[InputField[],"KeyDown":>Switch[CurrentValue@"EventKey","f",If[g>8&&f>0,f--;g-=9],"s",s=0,"p",If[p>0,p--;h+=9],"b",If[m>8,m-=9;p++],"t",If[m>8,m-=9;f++]]],"
Health: ",h,"
Money: ",m,"
Food: ",f,"
Hunger: ",g,"
Sleep: ",s,"
Potions: ",p}]

Satır sonları önemlidir çünkü onlar Rowyerine kullanabilmek için dizede newline karakterler Column. Bunu bir Mathematica not defterinde değerlendirirseniz şöyle bir şey görmelisiniz:

Tamagotchi simülasyonu

Giriş alanını tıklatmanız Dynamicve giriş alanının güncellenmesine neden olmadan önce karakterinizi hızlı bir şekilde (bir saniyeden az) yazmanız gerekir . Bu baş ağrısından EventHandlerbir öğe olmak yerine kendi hücresindeyse tamamen önlenebilir Row, ancak bu programın bayt sayısını büyük ölçüde artıracak bir .nb dosyası olarak kaydedilmesini gerektirecektir.


İyi iş! Gibi bir yapı kullanacaktım CurrentValue[EvaluationNotebook[], NotebookEventActions] = {"KeyDown" :> Switch[CurrentValue@"EventKey", "f", If[g > 8 && f > 0, f--; g -= 9], "s", s = 0, "p", If[p > 0, p--; h += 9], "b", If[m > 8, m -= 9; p++], "t", If[m > 8, m -= 9; f++]]};... bu, bir giriş alanına tıklamaktan kaçınmanıza izin vermelidir. , PassEventsDown -> TrueBu kodun sonuna seçeneği eklemek, not defterini düzenlemeye devam etmenizi sağlar, ancak bayt tasarrufları için en sonunda kaldırılabilir :)
Greg Martin

Teşekkürler, bu tam olarak başlangıçta aradığım işlevsellik! Ne yazık ki şu an sahip olduğumdan daha uzun görünüyor.
ngenisis

2

C # 6, 567563 bayt

using System;using System.Threading;class T{int L,M,F=10,H,S,P;static void Main(){T t=new T();}T(){M=L=100;var W=new Thread(new ThreadStart(Q));W.Start();while(1>0){var r=Console.Read();bool B=0>1,K=1>0;if(r=='f'&H>8&F>0){F--;H-=9;B=K;}if(r=='s'){S=0;B=K;}if(r=='p'&P>0){P--;L+=9;B=K;}if(r=='b'&M>8){M-=9;P++;B=K;}if(r=='t'&M>8){M-=9;F++;B=K;}if(B)p();}}void Q(){while(1>0){H++;S++;if(H>79)L--;if(S>79){S=0;H+=9;}if(L>79)M++;L*=L/L;p();Thread.Sleep(500);}}void p(){Console.Write($"\nhealth: {L}\nhunger: {H}\nsleep: {S}\nfood: {F}\nmoney: {M}\npotions: {P}\n");}}

Ungolfed:

using System;
using System.Threading;
class T
{
    int L,M,F=10,H,S,P;
    static void Main()
    {
        T t=new T();
    }
    T()
    {
        M=L=100;
        var W=new Thread(new ThreadStart(Q));
        W.Start();
        while(1>0)
        {
            var r=Console.Read();
            var B=0>1;
            if(r=='f'&H>8&F>0){F--;H-=9;B=1>0;}
            if(r=='s'){S=0;B=1>0;}
            if(r=='p'&P>0){P--;L+=9;B=1>0;}
            if(r=='b'&M>8){M-=9;P++;B=1>0;}
            if(r=='t'&M>8){M-=9;F++;B=1>0;}
            if(B)p();
        }
    }
    void Q()
    {
        while(1>0)
        {
            H++;S++;
            if(H>79)L--;
            if(S>79){S=0;H+=9;}
            if(L>79)M++;
            L*=L/L;
            p();
            Thread.Sleep(500);
        }
    }
    void p()
    {
        Console.Write($"\nhealth: {L}\nhunger: {H}\nsleep: {S}\nfood: {F}\nmoney: {M}\npotions: {P}\n");
    }
}

1

Clojure, 1224 bayt

V2

Bir durum nesnesinin içinde olmak yerine tüm atomları gevşek değişkenler haline getirdi. Bu tek başına bir çok koddan kurtuldu. Ayrıca kısayol işlevleri oluşturulan a!ve s!gelen toplayıp çıkarmada atoms(temelde gibi davranan daha kolay +=ve -=Clojure bu operatörler olmadığı için).

Ben muhtemelen ortadan olabileceğini fark etti atomben içine anahtar girişi entegre yönetiyorsanız s loop. Görmem gerekecek.

(ns bits.golf.pet.v2.petms)(def h(atom 100))(def j(atom 0))(def s(atom 0))(def f(atom 10))(def p(atom 0))(def m(atom 100))(defn a[sa n](swap! sa #(+ % n)))(defn v[sa n](swap! sa #(- % n)))(defn c[](a j 1)(a s 1)(if(>=@j 80)(v h 1))(if (>=@s 80)(do(reset! s 0)(a j 9)))(if(>= @h 80)(a m 1)))(defn l[k](case k\f(if(> @j 8)(do(v f 1)(v j 9)))\s(reset! s 0) \p(if(>@p 0)(do(v p 1)(a h 9)))\b(if(> @m 8)(do(v m 9)(a p 1)))\t(if(>@m 8)(do(v m 9)(a f 1)))nil))(defn b[](.start(Thread.^Runnable(fn[](while(>@h 0)(l(first (read-line))))))))(defn -main[](b)(while(>@h 0)(Thread/sleep 500)(c)(println(str"Health: "@h"\nHunger: " @j"\nSleep: "@s"\nFood: "@f"\nPotions: "@p"\nMoney:"@m"\n")))(println"You died!\n"))

Ungolfed:

(ns bits.golf.pet.v2.pet)

; 100 0 0 10 0 100
(def he (atom 100))
(def hu (atom 0))
(def sl (atom 0))
(def fo (atom 10))
(def po (atom 0))
(def mo (atom 100))

(defn a! [sa n]
  (swap! sa #(+ % n)))

(defn s! [sa n]
  (swap! sa #(- % n)))

(defn apply-rules []
    (a! hu 1)
    (a! sl 1)
    (if (>= @hu 80)
      (s! he 1))
    (if (>= @sl 80)
      (do
        (reset! sl 0)
        (a! hu 9)))
    (if (>= @he 80)
      (a! mo 1)))

(defn handle-keypress [k]
    (case k
      \f (if (> @hu 8)
           (do
             (s! fo 1)
             (s! hu 9)))
      \s (reset! sl 0)
      \p (if (> @po 0)
           (do
             (s! po 1)
             (a! he 9)))
      \b (if (> @mo 8)
           (do
             (s! mo 9)
             (a! po 1)))
      \t (if (> @mo 8)
           (do
             (s! mo  9)
             (a! fo 1)))
      nil))


(defn start-listener []
  (.start
    (Thread. ^Runnable
      (fn []
        (while (> @he 0)
            (handle-keypress (first (read-line))))))))

(defn -main []
  (start-listener)
  (while (> @he 0)
    (Thread/sleep 500)

    (apply-rules)

    (println (str
               "Health: " @he "\n"
               "Hunger: " @hu "\n"
               "Sleep: " @sl "\n"
               "Food: " @fo "\n"
               "Potions: " @po "\n"
               "Money:" @mo "\n")))

  (println "You died!\n"))

V1

Ohdeargod. Burada iyileştirme için kesinlikle yer. Bu tür bir sorun yan etkileri ile yapmak en kolay ve Clojure işlevsel, bu yüzden atomgerekli kod miktarını azaltmak için s kötüye çalışıyorum . Ne yazık ki, bir plana girmedim, bu yüzden şu anda bir tür gelişigüzel. Yine de küçültmek için birkaç fikir edindim.

Tam bir program. Koşarak çalıştırılabilir -main.

(ns bits.golf.pet)(defrecord S[he hu sl fo po mo])(def new-state(->S 100 0 0 10 0 100))(def state(atom new-state))(defn update![sa k f](swap! sa #(update % k f)))(defn apply-rules[s](let [s' (atom s)u! #(update! s' %1 %2)g #(get @s' %)](u! :hu inc)(u! :sl inc)(if(>=(g :hu)80)(u! :he dec))(if(>= (g :sl)80)(do(u! :sl (fn[_]0))(u! :hu #(+ % 9))))(if(>=(g :he)80)(u! :mo inc))@s'))(defn get-input [](let [raw (read-line)](first raw)))(defn handle-keypress[s k](let [s'(atom s)u! #(update! s' %1 %2)g #(get @s' %)](case k\f(if (> (g :hu)8)(do(u! :fo dec)(u! :hu #(- % 9))))\s(u! :sl (fn [_] 0))\p(if(> (g :po)0)(do(u! :po dec)(u! :he #(+ % 9))))\b(if(>(g :mo))(do(u! :mo #(- % 9))(u! :po inc)))\t(if(>(g :mo)8)(do(u! :mo #(- % 9))(u! :fo inc)))nil@s')))(defn start-listener[](.start(Thread.^Runnable(fn[](while true(let[k(get-input)](swap! state #(handle-keypress % k))))))))(defn -main[](start-listener)(let[g #(get @%1 %2)](while true(Thread/sleep 500)(swap! state #(apply-rules %))(println(str"Health: "(g state :he)"\nHunger: "(g state :hu)"\n""Sleep: " (g state :sl)"\nFood: "(g state :fo)"\nPotions: "(g state :po)"\n""Money:"(g state :mo)"\n"))(if(<=(g state :he)0)(do(println"You died!\n")(reset! state new-state))))))

Ungolfed:

(ns bits.golf.pet)

(defrecord State [he hu sl fo po mo])

(def new-state (->State 100 0 0 10 0 100))

(def state (atom new-state))

(defn update! [sa k f]
  (swap! sa #(update % k f)))

(defn apply-rules [s]
  (let [s' (atom s)
        u! #(update! s' %1 %2)
        g #(get @s' %)]
    (u! :hu inc)
    (u! :sl inc)
    (if (>= (g :hu) 80)
      (u! :he dec))
    (if (>= (g :sl) 80)
      (do
        (u! :sl (fn [_] 0))
        (u! :hu #(+ % 9))))
    (if (>= (g :he) 80)
      (u! :mo inc))
    @s'))

(defn get-input []
  (let [raw (read-line)]
    (first raw)))

(defn handle-keypress [s k]
  (let [s' (atom s)
        u! #(update! s' %1 %2)
        g #(get @s' %)]
    (case k
      \f (if (> (g :hu) 8)
           (do
             (u! :fo dec)
             (u! :hu #(- % 9))))
      \s (u! :sl (fn [_] 0))
      \p (if (> (g :po) 0)
           (do
             (u! :po dec)
             (u! :he #(+ % 9))))
      \b (if (> (g :mo))
           (do
             (u! :mo #(- % 9))
             (u! :po inc)))
      \t (if (> (g :mo) 8)
           (do
             (u! :mo #(- % 9))
             (u! :fo inc)))
      nil
      @s')))

(defn start-listener []
  (.start
    (Thread. ^Runnable
      (fn []
        (while true
          (let [k (get-input)]
            (swap! state #(handle-keypress % k))))))))

(defn -main []
  (start-listener)
  (let [g #(get @%1 %2)]
    (while true
      (Thread/sleep 500)

      (swap! state #(apply-rules %))

      (println (str
                 "Health: " (g state :he) "\n"
                 "Hunger: " (g state :hu) "\n"
                 "Sleep: " (g state :sl) "\n"
                 "Food: " (g state :fo) "\n"
                 "Potions: " (g state :po) "\n"
                 "Money:" (g state :mo) "\n"))

      (if (<= (g state :he) 0)
        (do
          (println "You died!\n\n\n\n\n")
          (reset! state new-state))))))

Orada güzel bir kod var.
16:51

@ender_scythe Ya. Yapma applying-rulesve handle-keypresssaf gibi bazı yerlerde yarı iyi kodlama uygulamalarına bağlı kalmaya çalışıyordum . Şu anda bir "vidala" sürümü yazıyorum.
Carcigenicate
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.