Erstelle ein Benutzerprofil-Minispiel

49

Gestern bin ich über eine sehr clevere Sache gestolpert.

Minitechs Tic-Tac-Toe-Profilspiel

Ja, das ist eine funktionierende Implementierung von Tic-Tac-Toe auf einer Benutzerprofilseite von @minitech. Natürlich musste ich in dem Moment, in dem ich es sah, seine Idee rückgängig machen und ihn einsetzten : P

Mellamokbs Türme von Hanoi-Profil-Spiel

Hier ist mein eigenes Beispiel, das direkt in den Beitrag eingebettet ist. Es ist ein bisschen fehlerhaft, da ich für einige Implementierungsdetails keine gute Lösung gefunden habe. Manchmal wird ein Stift nach dem Klicken erst dann ordnungsgemäß aktualisiert, wenn eine andere Seite aktualisiert wird:

Türme von Hanoi

http://hanoi.kurtbachtold.com/hanoi.php/text

http://hanoi.kurtbachtold.com/hanoi.php/1 http://hanoi.kurtbachtold.com/hanoi.php/2 http://hanoi.kurtbachtold.com/hanoi.php/3

Zurücksetzen

Kannst du es besser machen?

  • Erstelle ein funktionierendes Spiel in deiner geposteten Antwort (oder auf deiner Benutzerprofilseite). Dazu müssen Sie einen Webserver, den Sie besitzen, entsprechend konfigurieren (oder ein Programm schreiben, das als Webserver fungiert) und den Inhalt in einen Beitrag einbetten. Dabei müssen Sie anhand des Referers ermitteln, welche Befehle der Benutzer an das Spiel gibt.
  • Die coolste Idee (die meisten Stimmen) gewinnt den Wettbewerb bis zum Canada Day (Sonntag, 1. Juli 2012, 23:59 Uhr EST)
  • Bei einem Gleichstand gewinnt die ältere Antwort.
mellamokb
quelle
1
+1 Einfache, aber geniale Idee! BTW - für den Termin Ich denke , Sie meinen Juni 2 2012
Cristian Lupascu
Derp, ja, habe ich, danke :)
mellamokb
1
@boothby: Ich habe tatsächlich darüber nachgedacht, meine Antwort zu löschen. Die Absicht war, ein konkretes Beispiel zu liefern, um den Wettbewerb nicht zu gewinnen (oder Stimmen, die ich nicht so sehr für Repräsentanten halte). Können Sie dem Wettbewerb konstruktive Vorschläge unterbreiten? Wie soll der Abgabetermin lauten? Wie sollte die Spezifikation geändert werden, um Sie zur Teilnahme zu motivieren?
Mellamokb
4
Mir ist gerade aufgefallen, dass die KI von Minitech kein perfektes Tic-Tac-Toe-Spiel spielen kann. Spielen Sie in der Mitte, unten links, oben in der Mitte, in der Mitte rechts und in der Mitte links.
PhiNotPi
1
@ Mr.Wizard: Funktioniert es gut mit FF 12.0 und Windows 7? Könnten Sie mehr Details darüber posten, was nicht funktioniert?
ChristopheD

Antworten:

27

Conways Spiel des Lebens

+1 Generation - +5 Generationen - Vergrößern - Verkleinern

Belastungsmuster: Zufall - Segelflugzeug - Gunstar - Schnecke - Lwss - Lightspeedoscillator1 - Tumbler

Verwendete Python- und SVG-Ausgabe. Ich habe zuerst versucht, einzelne Pixel zu verwenden (damit Sie einzelne Zellen umschalten können), aber es hat nicht funktioniert, da der Browser die Bilder nicht in der richtigen Reihenfolge lädt. Auch viel größere Muster sind so möglich, ohne meinen Webserver zum Absturz zu bringen.

Aktualisieren:

Ich hatte etwas Spaß mit Python und fügte einige Funktionen und Verbesserungen hinzu:

  • HUD mit Bevölkerungszahl, Zoom und Namen hinzugefügt
  • Muster im rle-Format können jetzt über den Parameter (zB ) geladen werden ( lange Liste , via ). Die Dateigröße ist auf 1,5 kB begrenztpattern?pattern=glider
  • Über den nextParameter können n Generationen, jeweils auf 5 begrenzt, weitergeleitet werden
  • Leicht verbesserter Algorithmus. Es ist zwar nicht wirklich schnell, ich möchte, dass dies einfach bleibt
  • Es funktioniert jetzt auch eigenständig (verwendet entweder den Referer oder eine eigene Abfragezeichenfolge): https://copy.sh/fcgi-bin/life2.py?pattern=gosperglidergun


sessions = {}

WIDTH = 130
HEIGHT = 130
RULE = (3,), (2, 3)

def read_pattern(filename, offset_x, offset_y):

    filename = PATH + filename + '.rle.gz'

    try:
        if os.stat(filename).st_size > 1500:
            return ['pattern too big', set()]
    except OSError as e:
        return ['could not find pattern', set()]

    file = gzip.open(filename)

    x, y = offset_x, offset_y
    name = ''
    pattern_string = ''
    field = []

    for line in file:
        if line[0:2] == '#N':
            name = line[2:-1]
        elif line[0] != '#' and line[0] != 'x':
            pattern_string += line[:-1]

    for count, chr in re.findall('(\d*)(b|o|\$|!)', pattern_string):
        count = int(count) if count else 1

        if chr == 'o':
            for i in range(x, x + count):
                field.append( (i, y) )
            x += count
        elif chr == 'b':
            x += count
        elif chr == '$':
            y += count
            x = offset_x
        elif chr == '!':
            break

    file.close()

    return [name, set(field)]



def next_generation(field, n):

    for _ in range(n):

        map = {}

        for (x, y) in field:
            for (i, j) in ( (x-1, y-1), (x, y-1), (x+1, y-1), (x-1, y), (x+1, y), (x-1, y+1), (x, y+1), (x+1, y+1) ):
                map[i, j] = map[i, j] + 1 if (i, j) in map else 1

        field = [
            (x, y)
            for x in range(0, WIDTH)
            for y in range(0, HEIGHT)
            if (x, y) in map
            if ( (map[x, y] in RULE[1]) if (x, y) in field else (map[x, y] in RULE[0]) )
        ]

    return field


def life(env, start):


    if 'REMOTE_ADDR' in env:
        client_ip = env['REMOTE_ADDR']
    else:
        client_ip = '0'

    if not client_ip in sessions:
        sessions[client_ip] = read_pattern('trueperiod22gun', 10, 10) + [2]

    session = sessions[client_ip]

    if 'HTTP_REFERER' in env:
        query = urlparse.parse_qs(urlparse.urlparse(env['HTTP_REFERER']).query, True)
    elif 'QUERY_STRING' in env:
        query = urlparse.parse_qs(env['QUERY_STRING'], True)
    else:
        query = None

    timing = time.time()

    if query:
        if 'next' in query:
            try:
                count = min(5, int(query['next'][0]))
            except ValueError as e:
                count = 1
            session[1] = set( next_generation(session[1], count) )
        elif 'random' in query:
            session[0:2] = 'random', set([ (random.randint(0, WIDTH), random.randint(0, HEIGHT)) for _ in range(800) ])
        elif 'pattern' in query:
            filename = query['pattern'][0]
            if filename.isalnum():
                session[0:2] = read_pattern(filename, 10, 10)
        elif 'zoomin' in query:
            session[2] += 1
        elif 'zoomout' in query and session[2] > 1:
            session[2] -= 1

    timing = time.time() - timing

    start('200 Here you go', [
        ('Content-Type', 'image/svg+xml'), 
        ('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'), 
        ('Expires', 'Tue, 01 Jan 2000 12:12:12 GMT')
    ])

    pattern_name, field, zoom = session

    yield '<?xml version="1.0" encoding="UTF-8"?>'
    yield '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'
    yield '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="400px" height="200px">'
    yield '<!-- finished in %f -->' % timing
    yield '<text x="0" y="10" style="font-size:10px">Population: %d</text>' % len(field)
    yield '<text x="100" y="10" style="font-size:10px">Zoom: %d</text>' % zoom
    yield '<text x="180" y="10" style="font-size:10px; font-weight:700">%s</text>' % pattern_name
    yield '<line x1="0" y1="15" x2="666" y2="15" style="stroke:#000; stroke-width:1px" />'

    for (x, y) in field:
        yield '<rect x="%d" y="%d" width="%d" height="%d"/>' % (zoom * x, zoom * y + 20, zoom, zoom)

    yield '</svg>'


from flup.server.fcgi import WSGIServer
import random
import re
import gzip
import os
import urlparse
import time

WSGIServer(life).run()

Sie können meinen Code als Vorlage für weitere Python-Fastcgi-Einreichungen verwenden.

Kopieren
quelle
+1 Super! Ein Vorschlag: Hänge #5946an deine Links an und sie springen nach jedem Update zurück zu deinem Beitrag.
mellamokb
hmm .. zumindest hat es funktioniert, als ich es ausprobiert habe .. ah. Denn in Towers of Hanoi klickt man immer auf verschiedene Stifte. hmm
mellamokb
@mellamokb es funktioniert, aber Sie können jetzt nicht zweimal auf denselben Link klicken
kopieren Sie
Ja, ich habe gerade gemerkt, dass lol. Sie können einen Haftungsausschluss geben, wenn Sie die nächste Generation ausführen, drücken Sie einfach F5 für zukünftige Iterationen, anstatt nextnach dem ersten Mal immer wieder auf den Link zu klicken .
Mellamokb
1
@ Mellamokb danke. Meiner Meinung nach müssen Sie Antworten auf dieser Plattform nicht wirklich akzeptieren, da es so aussieht, als wäre die Herausforderung geschlossen
kopieren Sie den
35

Stapel Exchange Hangman

Errate die Namen der Stack Exchange-Websites in diesem Hangman-Spiel:



A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
New game


Dies wurde mit ASP.NET MVC 3.0 durchgeführt . Hier ist der Code von Controller, der den Trick macht:

public class HangmanController : Controller
{
    public ActionResult Index()
    {
        var game = Session["hangman"] as HangmanGame ?? HangmanGame.New();

        game = ExecuteGameCommand(game);

        Session["hangman"] = game;

        var imageRenderer = new HangmanImageRenderer(game);
        return new ImageResult(imageRenderer.Render());
    }

    private HangmanGame ExecuteGameCommand(HangmanGame game)
    {
        var referrerQuery = Request.UrlReferrer != null ? Request.UrlReferrer.Query : string.Empty;

        if (referrerQuery.Contains("_new_hangman_"))
            return HangmanGame.New();

        if(game.IsOver())
            return game;

        var chosenLetter = HangmanGame.ValidLetters
            .FirstOrDefault(letter => referrerQuery.Contains(String.Format("_hangman_{0}_", letter)));

        if (chosenLetter != default(char))
            game.RegisterGuess(chosenLetter);

        return game;
    }
}

Abgesehen von diesem Code gibt es drei weitere Klassen, die ich nicht aufgenommen habe, da sie ziemlich lang und unkompliziert sind:

  • HangmanGame - Hier werden die Geschäftsregeln für Spiele implementiert
  • HangmanImageRenderer - Die Klasse, die alle GDI-Hässlichkeit einschließt
  • ImageResult- Eine benutzerdefinierte Methode ActionResult, mit der ein dynamisch generiertes Bild zurückgegeben wird

Die gesamte Codeliste finden Sie unter http://pastebin.com/ccwZLknX

Cristian Lupascu
quelle
+1 Wow, ihr seid großartig :). Wie die bisherigen Ideen!
Mellamokb
Cool, noch nie von appharbor.com gehört. Zahlen Sie wirklich, um Ihre Antwort zu hosten?
Mellamokb
@mellamokb nein, ich verwende den kostenlosen Hosting-Plan von Appharbor. Wenn dies sehr angeklickt wird, muss ich wohl bezahlen ... :)
Cristian Lupascu
2
Ich wollte erwähnen, dass ich bei Bedarf benutzerdefiniertes Subdomain-Hosting und FTP-Zugriff auf meine Hosting-Site bereitstellen kann.
Mellamokb
@mellamokb danke, aber ich denke, dieses Hosting wird ausreichen. Ich habe nur über viele Klicks gescherzt. :)
Cristian Lupascu
19

Clojoban! [WIP]

Ich wollte ein größeres Spiel daraus machen, um Clojure zu lernen , also dauerte es eine Weile, bis ich es geschafft hatte (und es wurde ziemlich groß). Ich hatte viel Spaß dabei, übrigens!

Clojoban! Restart levelNew game

. .

- No-op*

. .

** (hier klicken, wenn das Spiel nicht mehr reagiert) *

Anleitung

Sie sind Robby Robby, ein hart arbeitender Roboter. Sie arbeiten FlipCo Industriesals Schwerlastträger. Ihre Aufgabe ist es, jeweils so wenige Schritte wie möglich box Eine Boxzu goal Ein Zielverbringen. FlipCoDie Einrichtungen sind GEFÄHRLICH . Es gibt viele Herausforderungen und besondere Orte zu entdecken.

Wenn Sie nicht weiterkommen, klicken Sie auf Restart level(aber Ihre Schrittzahl wird nicht zurückgesetzt!)


Sie können auch auf der Startseite von Clojoban spielen (obwohl dies den Zweck der Herausforderung ruiniert). Es behebt das berüchtigte Ankerproblem, erfordert keine Cross-Site-Cookies und Sie können mit den Pfeiltasten Ihrer Tastatur spielen! Sie können auch auf meiner Benutzerprofilseite spielen, ohne das lästige Ankerproblem zu haben.

In Firefox flackert das Bild beim Laden nicht, daher ist es etwas komfortabler zu spielen.

Dieses Spiel ist bei weitem noch nicht abgeschlossen, Clojoban ist noch in Arbeit . Den vollständigen Quellcode finden Sie auf der GitHub-Projektseite von Clojoban . Es gibt einige Informationen in der Readme über einen Beitrag . Ich brauche auch Level! Siehe das Ebenenformat in den Beispielebenen . Sie können einen Blick auf Clojobans Issue Tracker werfen und sehen, was als nächstes kommt!

Álvaro Cuesta
quelle
Jetzt ist Ihr Ruf 11 :)
mellamokb
@ Mellamokb danke! Spiel ist jetzt eingebettet :)
Álvaro Cuesta
Anscheinend bekam dies nicht viel Aufmerksamkeit. Irgendwelche Tipps zur Verbesserung?
Álvaro Cuesta,
Ihre Antwort ist gut, ich denke, diese Frage hat insgesamt stagniert. Ich habe in den letzten Tagen nicht viel Aktivität oder Stimmen gesehen.
Mellamokb
Das ist ein tolles Spiel! Ich denke, Sie sollten eine eigenständige Version erstellen. Ich kam in die dritte Ebene und ließ den No-Op-Knopf los. :) Wie auch immer, tolle Arbeit!
Cristian Lupascu
17

Matze

http://phpshizzle.t15.org/sogolf_maze/maze.php -
New Noop button

Ich habe mit dem PHP-Labyrinthgenerator begonnen, den ich hier gefunden habe: http://dev.horemag.net/2008/03/01/php-maze-generation-class/ .

BEARBEITEN : Die Ausgabe wurde in PNG anstatt in SVG geändert (für eine bessere Cross-Browser-Kompatibilität).

BEARBEITEN 2: Es wurde ein Header zum Korrigieren der IE-Cookie-Kompatibilität hinzugefügt. Sollte nun in allen gängigen Browsern korrekt funktionieren.

Das Bild wird nicht aktualisiert, wenn Sie zweimal dieselbe Richtung einschlagen (aufgrund der Ankerverbindungen). Drücken Sie das zweite Mal F5 oder spielen Sie das Labyrinth in meinem Stapelüberlaufprofil .

BEARBEITEN 3: Es wurde eine No-Op-Schaltfläche hinzugefügt, damit Sie problemlos zweimal in dieselbe Richtung fahren können (siehe Kommentare unten).

<?php
// based upon the maze generator by Evgeni Vasilev (PHP Adaptation)
// see http://dev.horemag.net/2008/03/01/php-maze-generation-class/
class Maze
{
  var $maze = array();
  var $mx = 0;
  var $my = 0;
  var $xplayer = 1;
  var $yplayer = 1;

  function Maze($mx, $my)
  {
    $mx +=2;
    $my +=2;
    $this->mx = $mx;
    $this->my = $my;
    $dx = array( 0, 0, -1, 1 );
    $dy = array( -1, 1, 0, 0 );
    $todo = array(); 
    $todonum = 0;

    for ($x = 0; $x < $mx; ++$x){
      for ($y = 0; $y < $my; ++$y){
        if ($x == 0 || $x == $mx-1 || $y == 0 || $y == $my-1) {
          $this->maze[$x][$y] = 32;
        } else {
          $this->maze[$x][$y] = 63;
        }
      }
    }
    $x = rand(1, $mx-2); $y = rand(1, $my-2);
    $x = 1; $y = 1;
    $this->maze[$x][$y] &= ~48;
    for ($d = 0; $d < 4; ++$d){
      if (($this->maze[$x + $dx[$d]][$y + $dy[$d]] & 16) != 0) {
        $todo[$todonum++] = (($x + $dx[$d]) << 16) | ($y + $dy[$d]);
        $this->maze[$x + $dx[$d]][$y + $dy[$d]] &= ~16;
      }
    }

    while ($todonum > 0) {
      $n = rand(0, $todonum-1);
      $x = $todo[$n] >> 16;
      $y = $todo[$n] & 65535;
      $todo[$n] = $todo[--$todonum];
      do {
        $d = rand(0, 3);
      } while (($this->maze[$x + $dx[$d]][$y + $dy[$d]] & 32) != 0);
      $this->maze[$x][$y] &= ~((1 << $d) | 32);
      $this->maze[$x + $dx[$d]][$y + $dy[$d]] &= ~(1 << ($d ^ 1));
      for ($d = 0; $d < 4; ++$d){
        if (($this->maze[$x + $dx[$d]][$y + $dy[$d]] & 16) != 0) {
          $todo[$todonum++] = (($x + $dx[$d]) << 16) | ($y + $dy[$d]);
          $this->maze[$x + $dx[$d]][$y + $dy[$d]] &= ~16;
        }
      }
    }
    $this->maze[1][1] &= ~1;
    $this->maze[$mx-2][$my-2] &= ~2;
  }

  function _drawLine($img,$color, $x1, $y1, $x2, $y2)
  {
    imageline($img, $x1, $y1, $x2, $y2, $color);
  }

  function _drawPlayer($img, $x, $y, $r, $colorborder, $colorfill)
  {
    imagefilledellipse($img, $x, $y, $r, $r, $colorfill);
    imageellipse($img, $x, $y, $r, $r, $colorborder);
  }

  function _drawWin($img, $color)
  {
    imagestring($img, 5, 170, 90, "YOU WIN!", $color);
  }

  function movePlayerDown()
  {
    if ($this->yplayer+1 < $this->my-1 && ($this->maze[$this->xplayer][$this->yplayer] & 2) == 0)
    $this->yplayer++;
  }

  function movePlayerUp()
  {
    if ($this->yplayer-1 > 0 && ($this->maze[$this->xplayer][$this->yplayer] & 1) == 0)
      $this->yplayer--;
  }

  function movePlayerRight()
  {
    if ($this->xplayer+1 < $this->mx-1 && ($this->maze[$this->xplayer][$this->yplayer] & 8) == 0)
      $this->xplayer++;
  }  

  function movePlayerLeft()
  {
    if ($this->xplayer-1 > 0 && ($this->maze[$this->xplayer][$this->yplayer] & 4) == 0)
      $this->xplayer--;
  }  

  function renderImage($xs, $ys)
  {
    $off = 0;
    $w = ($this->mx*$xs)+($off*2); $h = ($this->my*$ys)+($off*2);
    $img = imagecreatetruecolor($w, $h);
    imagesetthickness($img, 2);
    $fg = imagecolorallocate($img, 0, 0, 0);
    $bg = imagecolorallocate($img, 248, 248, 248);
    $red = imagecolorallocate($img, 255, 0, 0);
    imagefill($img, 0, 0, $bg);
    if (($this->xplayer == $this->mx-2) && ($this->yplayer == $this->my-2)) {
      $this->_drawWin($img, $red);
      return $img;
    }

    for ($y = 1; $y < $this->my-1; ++$y) {
      for ($x = 1; $x < $this->mx-1; ++$x){
        if (($this->maze[$x][$y] & 1) != 0)
          $this->_drawLine ($img, $fg, $x * $xs + $off, $y * $ys + $off, $x * $xs + $xs + $off, $y * $ys + $off);
        if (($this->maze[$x][$y] & 2) != 0)
          $this->_drawLine ($img, $fg, $x * $xs + $off, $y * $ys + $ys + $off, $x * $xs + $xs + $off, $y * $ys + $ys + $off);
        if (($this->maze[$x][$y] & 4) != 0)
          $this->_drawLine ($img, $fg, $x * $xs + $off, $y * $ys + $off, $x * $xs + $off, $y * $ys + $ys + $off);
        if (($this->maze[$x][$y] & 8) != 0)
          $this->_drawLine ($img, $fg, $x * $xs + $xs + $off, $y * $ys + $off, $x * $xs + $xs + $off, $y * $ys + $ys + $off);
        if ($x == $this->xplayer && $y == $this->yplayer) {
          $this->_drawPlayer ($img, $x * $xs + ($xs/2), $y * $ys + ($ys/2), 14, $fg, $red);
        }
      }
    }
    return $img;
  }
}
header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"');
session_start();
$orig_url = $_SERVER['HTTP_REFERER'];
if (!isset($_SESSION['maze']) || strpos($orig_url, 'resetmaze')){
    $_SESSION['maze'] = new Maze(25,10);
}
$maze = $_SESSION['maze'];
if (strpos($orig_url, 'playerdown')) { $maze->movePlayerDown(); }
if (strpos($orig_url, 'playerup')) { $maze->movePlayerUp(); }
if (strpos($orig_url, 'playerright')) { $maze->movePlayerRight(); }
if (strpos($orig_url, 'playerleft')) { $maze->movePlayerLeft(); }
$img = $maze->renderImage(16,16);
header("Content-Type: image/png");
imagepng($img);
imagedestroy($img);
?>
ChristopheD
quelle
1
+1 Schön! Fügen Sie für eine bessere Erfahrung #answer-6171am Ende Ihrer Links hinzu. Sonst hat niemand genug Geduld, um das Labyrinth zu lösen.
Cristian Lupascu
@W0lf: Danke. Ich habe darüber nachgedacht, die #Links einzuschließen, aber das Problem ist, dass sie die Seite nicht aktualisieren, wenn Sie zweimal dieselbe Richtung einschlagen (was in einem Labyrinth passieren kann ;-). Ich habe sie jetzt hinzugefügt, damit die Leute beim zweiten Mal die Taste F5 drücken müssen, wenn sie dieselbe Richtung einschlagen möchten. Eine andere Möglichkeit ist, es hier zu spielen (mein SO-Profil: stackoverflow.com/users/81179/christophed )
ChristopheD
Ich würde mir einen einfachen Link ohne Bedienung (Aktualisieren?)
Vorstellen
@kaoD: Ohne die Ankerteile ( #), die zur richtigen Antwort auf die Frage springen (intern, ohne Seitenaktualisierung), würde eine einfache Seitenaktualisierung problemlos funktionieren (wie Sie in meinem verknüpften Profil sehen können, in dem dasselbe Labyrinth auch verfügbar ist). . Das Problem wäre dann aber, dass Sie sich nach jeder Aktualisierung ganz oben auf der Seite befinden. Das eigentliche Problem besteht darin, dass wir in Bezug auf das, was wir hier auf StackOverflow in eine Antwort aufnehmen können, nur sehr begrenzt sind (natürlich aus gutem Grund). Beispielsweise können wir kein willkürliches Javascript verwenden. Ich habe keine Ahnung, wie es einfach wird.
ChristopheD
Sie können den Anker immer noch haben und er wird direkt zu Ihrem Beitrag weitergeleitet, aber mit einer anderen URL (die ein korrektes Gameplay ermöglicht) finde ich die F5-Methode klobig.
kaoD
14

2-Spieler-Pokémon-Schach [In Bearbeitung]

Weil es auf diese Weise mehr Spaß macht. Eines Tages: KI, isometrisches Gitter und Schatten!

http://minite.ch/chess/?i=1 http://minite.ch/chess/?i=2 http://minite.ch/chess/?i=3 http://minite.ch/ Schach /? i = 4 http://minite.ch/chess/?i=5 http://minite.ch/chess/?i=6 http://minite.ch/chess/?i=7 http: //minite.ch/chess/?i=8 
http://minite.ch/chess/?i=9 http://minite.ch/chess/?i=10 http://minite.ch/chess/ ? i = 11 http://minite.ch/chess/?i=12 http://minite.ch/chess/?i=13 http://minite.ch/chess/?i=14 http: // minite.ch/chess/?i=15 http://minite.ch/chess/?i=16 
http://minite.ch/chess/?i=17 http://minite.ch/chess/?i = 18 http://minite.ch/chess/?i=19 http://minite.ch/chess/?i=20 http://minite.ch/chess/?i=21http://minite.ch/chess/?i=22 http://minite.ch/chess/?i=23 http://minite.ch/chess/?i=24 
http://minite.ch/ Schach /? i = 25 http://minite.ch/chess/?i=26 http://minite.ch/chess/?i=27 http://minite.ch/chess/?i=28 http: //minite.ch/chess/?i=29 http://minite.ch/chess/?i=30 http://minite.ch/chess/?i=31 http://minite.ch/chess/ ? i = 32 
http://minite.ch/chess/?i=33 http://minite.ch/chess/?i=34 http://minite.ch/chess/?i=35 http: // minite.ch/chess/?i=36 http://minite.ch/chess/?i=37 http://minite.ch/chess/?i=38 http://minite.ch/chess/?i = 39 http://minite.ch/chess/?i=40 
http://minite.ch/chess/?i=41http://minite.ch/chess/?i=42 http://minite.ch/chess/?i=43 http://minite.ch/chess/?i=44 http://minite.ch/ Schach /? i = 45 http://minite.ch/chess/?i=46 http://minite.ch/chess/?i=47 http://minite.ch/chess/?i=48 
http: //minite.ch/chess/?i=49 http://minite.ch/chess/?i=50 http://minite.ch/chess/?i=51 http://minite.ch/chess/ ? i = 52 http://minite.ch/chess/?i=53 http://minite.ch/chess/?i=54 http://minite.ch/chess/?i=55 http: // minite.ch/chess/?i=56 
http://minite.ch/chess/?i=57 http://minite.ch/chess/?i=58 http://minite.ch/chess/?i = 59 http://minite.ch/chess/?i=60 http://minite.ch/chess/?i=61http://minite.ch/chess/?i=62 http://minite.ch/chess/?i=63 http://minite.ch/chess/?i=64

Kein en passant oder Rochade, sorry. Schachmatt- / Scheck- / Patterkennung implementiert werden. Sprites von hier: http://floatzel.net/pokemon/black-white/sprites/

Hier ist die Quelle:

<?php
session_start();

function kick() {
    header("Status: Forbidden\r\n", true, 403);
    header("Content-Type: text/plain\r\n");
    die('Go away.');
}

function isEnemy($item) {
    return $item !== -1 && $item & 8;
}

function iValidMoves($board, $type, $x, $y) {
    $results = array();

    switch($type) {
        case 0:
            # Pawn
            if($board[$y - 1][$x] === -1) {
                $results[] = array($x, $y - 1);

                if($y == 6 && $board[$y - 2][$x] === -1) $results[] = array($x, $y - 2);
            }

            if($x > 0 && isEnemy($board[$y - 1][$x - 1])) $results[] = array($x - 1, $y - 1);
            if($x < 7 && isEnemy($board[$y - 1][$x + 1])) $results[] = array($x + 1, $y - 1);

            break;
        case 1:
            # King
            if($x > 0 && $board[$y][$x - 1] & 8) $results[] = array($x - 1, $y);
            if($x > 0 && $y > 0 && $board[$y - 1][$x - 1] & 8) $results[] = array($x - 1, $y - 1);
            if($x > 0 && $y < 7 && $board[$y + 1][$x - 1] & 8) $results[] = array($x - 1, $y + 1);
            if($x < 7 && $board[$y][$x + 1] & 8) $results[] = array($x + 1, $y);
            if($x < 7 && $y > 0 && $board[$y - 1][$x + 1] & 8) $results[] = array($x + 1, $y - 1);
            if($x < 7 && $y < 7 && $board[$y + 1][$x + 1] & 8) $results[] = array($x + 1, $y + 1);
            if($y > 0 && $board[$y - 1][$x] & 8) $results[] = array($x, $y - 1);
            if($y < 7 && $board[$y + 1][$x] & 8) $results[] = array($x, $y + 1);

            break;
        case 2:
            # Queen
            # Downwards diagonal
            for($d = 1; $x + $d < 8 && $y + $d < 8; $d++) {
                if($board[$y + $d][$x + $d] & 8) {
                    $results[] = array($x + $d, $y + $d);

                    if($board[$y + $d][$x + $d] !== -1) break;
                } else {
                    break;
                }
            }

            for($d = -1; $x + $d >= 0 && $y + $d >= 0; $d--) {
                if($board[$y + $d][$x + $d] & 8) {
                    $results[] = array($x + $d, $y + $d);

                    if($board[$y + $d][$x + $d] !== -1) break;
                } else {
                    break;
                }
            }

            # Upwards diagonal
            for($d = 1; $x + $d < 8 && $y - $d >= 0; $d++) {
                if($board[$y - $d][$x + $d] & 8) {
                    $results[] = array($x + $d, $y - $d);

                    if($board[$y - $d][$x + $d] !== -1) break;
                } else {
                    break;
                }
            }

            for($d = -1; $x + $d >= 0 && $y - $d < 8; $d--) {
                if($board[$y - $d][$x + $d] & 8) {
                    $results[] = array($x + $d, $y - $d);

                    if($board[$y - $d][$x + $d] !== -1) break;
                } else {
                    break;
                }
            }

            # Horizontal
            for($d = 1; $x + $d < 8; $d++) {
                if($board[$y][$x + $d] & 8) {
                    $results[] = array($x + $d, $y);

                    if($board[$y][$x + $d] !== -1) break;
                } else {
                    break;
                }
            }

            for($d = -1; $x + $d >= 0; $d--) {
                if($board[$y][$x + $d] & 8) {
                    $results[] = array($x + $d, $y);

                    if($board[$y][$x + $d] !== -1) break;
                } else {
                    break;
                }
            }

            # Vertical
            for($d = 1; $y + $d < 8; $d++) {
                if($board[$y + $d][$x] & 8) {
                    $results[] = array($x, $y + $d);

                    if($board[$y + $d][$x] !== -1) break;
                } else {
                    break;
                }
            }

            for($d = -1; $y + $d >= 0; $d--) {
                if($board[$y + $d][$x] & 8) {
                    $results[] = array($x, $y + $d);

                    if($board[$y + $d][$x] !== -1) break;
                } else {
                    break;
                }
            }

            break;
        case 3:
            # Bishop
            # Downwards diagonal
            for($d = 1; $x + $d < 8 && $y + $d < 8; $d++) {
                if($board[$y + $d][$x + $d] & 8) {
                    $results[] = array($x + $d, $y + $d);

                    if($board[$y + $d][$x + $d] !== -1) break;
                } else {
                    break;
                }
            }

            for($d = -1; $x + $d >= 0 && $y + $d >= 0; $d--) {
                if($board[$y + $d][$x + $d] & 8) {
                    $results[] = array($x + $d, $y + $d);

                    if($board[$y + $d][$x + $d] !== -1) break;
                } else {
                    break;
                }
            }

            # Upwards diagonal
            for($d = 1; $x + $d < 8 && $y - $d >= 0; $d++) {
                if($board[$y - $d][$x + $d] & 8) {
                    $results[] = array($x + $d, $y - $d);

                    if($board[$y - $d][$x + $d] !== -1) break;
                } else {
                    break;
                }
            }

            for($d = -1; $x + $d >= 0 && $y - $d < 8; $d--) {
                if($board[$y - $d][$x + $d] & 8) {
                    $results[] = array($x + $d, $y - $d);

                    if($board[$y - $d][$x + $d] !== -1) break;
                } else {
                    break;
                }
            }

            break;
        case 4:
            # Knight
            if($x > 1 && $y > 0 && $board[$y - 1][$x - 2] & 8) $results[] = array($x - 2, $y - 1);
            if($x > 0 && $y > 1 && $board[$y - 2][$x - 1] & 8) $results[] = array($x - 1, $y - 2);
            if($x < 7 && $y > 1 && $board[$y - 2][$x + 1] & 8) $results[] = array($x + 1, $y - 2);
            if($x < 6 && $y > 0 && $board[$y - 1][$x + 2] & 8) $results[] = array($x + 2, $y - 1);
            if($x < 6 && $y < 7 && $board[$y + 1][$x + 2] & 8) $results[] = array($x + 2, $y + 1);
            if($x < 7 && $y < 6 && $board[$y + 2][$x + 1] & 8) $results[] = array($x + 1, $y + 2);
            if($x > 0 && $y < 6 && $board[$y + 2][$x - 1] & 8) $results[] = array($x - 1, $y + 2);
            if($x > 1 && $y < 7 && $board[$y + 1][$x - 2] & 8) $results[] = array($x - 2, $y + 1);

            break;
        case 5:
            # Rook
            # Horizontal
            for($d = 1; $x + $d < 8; $d++) {
                if($board[$y][$x + $d] & 8) {
                    $results[] = array($x + $d, $y);

                    if($board[$y][$x + $d] !== -1) break;
                } else {
                    break;
                }
            }

            for($d = -1; $x + $d >= 0; $d--) {
                if($board[$y][$x + $d] & 8) {
                    $results[] = array($x + $d, $y);

                    if($board[$y][$x + $d] !== -1) break;
                } else {
                    break;
                }
            }

            # Vertical
            for($d = 1; $y + $d < 8; $d++) {
                if($board[$y + $d][$x] & 8) {
                    $results[] = array($x, $y + $d);

                    if($board[$y + $d][$x] !== -1) break;
                } else {
                    break;
                }
            }

            for($d = -1; $y + $d >= 0; $d--) {
                if($board[$y + $d][$x] & 8) {
                    $results[] = array($x, $y + $d);

                    if($board[$y + $d][$x] !== -1) break;
                } else {
                    break;
                }
            }

            break;
    }

    return $results;
}

function invertRelationship($piece) {
    return $piece === -1 ? -1 : $piece ^ 8;
}

function invertPosition($position) {
    return array($position[0], 7 - $position[1]);
}

function invertBoard($board) {
    $invertedBoard = array();

    for($i = 7; $i > -1; $i--) {
        $invertedBoard[] = array_map('invertRelationship', $board[$i]);
    }

    return $invertedBoard;
}

function validMoves($x, $y) {
    global $board;

    $type = $board[$y][$x];

    if($type & 8) {
        return array_map('invertPosition', iValidMoves(invertBoard($board), $type & ~8, $x, 7 - $y));
    } else {
        return iValidMoves($board, $type, $x, $y);
    }
}

function shouldHighlight($x, $y) {
    global $highlight;

    foreach($highlight as $position) {
        if($position[0] == $x && $position[1] == $y) {
            return true;
        }
    }

    return false;
}

if(isset($_SESSION['board'])) {
    $board = $_SESSION['board'];
} else {
    $board = array(
        array(5 | 8, 4 | 8, 3 | 8, 1 | 8, 2 | 8, 3 | 8, 4 | 8, 5 | 8),
        array(0 | 8, 0 | 8, 0 | 8, 0 | 8, 0 | 8, 0 | 8, 0 | 8, 0 | 8),
        array(-1, -1, -1, -1, -1, -1, -1, -1),
        array(-1, -1, -1, -1, -1, -1, -1, -1),
        array(-1, -1, -1, -1, -1, -1, -1, -1),
        array(-1, -1, -1, -1, -1, -1, -1, -1),
        array(0, 0, 0, 0, 0, 0, 0, 0),
        array(5, 4, 3, 1, 2, 3, 4, 5)
    );
}

$back = array(
    imagecreatefrompng('back/16.png'),  # pawn
    imagecreatefrompng('back/6.png'),   # king
    imagecreatefrompng('back/149.png'), # queen
    imagecreatefrompng('back/37.png'),  # bishop
    imagecreatefrompng('back/25.png'),  # knight
    imagecreatefrompng('back/75.png')   # rook
);

$front = array(
    imagecreatefrompng('front/16.png'),     # pawn
    imagecreatefrompng('front/6.png'),      # king
    imagecreatefrompng('front/149.png'),    # queen
    imagecreatefrompng('front/37.png'),     # bishop
    imagecreatefrompng('front/25.png'),     # knight
    imagecreatefrompng('front/75.png')      # rook
);

$image = $_GET['i'];

if(ctype_digit($image)) {
    $image = (int)$image;
} else {
    kick();
}

if($image < 1 || $image > 64) {
    kick();
}

$highlight = array();

$referrer = $_SERVER['HTTP_REFERER'];
$action = null;

if(strpos($referrer, '?a=') > -1) {
    $action = substr($referrer, strpos($referrer, '?a=') + 3);
}

if($action !== null && $image === 1) { # Only do this once!
    if(!ctype_digit($action)) kick();
    $action = (int)$action;

    if($action < 1 || $action > 64) kick();

    $aX = ($action - 1) % 8;
    $aY = floor(($action - 1) / 8);

    if(isset($_SESSION['selected'])) {
        if($_SESSION['selected'] !== $action) {
            # Make sure the piece can actually move there.
            # If it can, move.
            # "Highlight" the places that the piece can move:
            $highlight = validMoves(($_SESSION['selected'] - 1) % 8, floor(($_SESSION['selected'] - 1) / 8));

            if(shouldHighlight($aX, $aY)) {
                # The move is good!
                $sX = ($_SESSION['selected'] - 1) % 8;
                $sY = floor(($_SESSION['selected'] - 1) / 8);
                $board[$aY][$aX] = $board[$sY][$sX];
                $board[$sY][$sX] = -1;

                # Now, rotate the board for the next person to play:
                $invertedBoard = invertBoard($board);
                $rotatedBoard = array();

                foreach($invertedBoard as $row) {
                    for($i = 0; $i < 4; $i++) {
                        $row[$i] ^= $row[7 - $i];
                        $row[7 - $i] ^= $row[$i];
                        $row[$i] ^= $row[7 - $i];
                    }

                    $rotatedBoard[] = $row;
                }

                $board = $rotatedBoard;
            }
        }

        unset($_SESSION['selected']);
    } elseif(($board[$aY][$aX] & 8) === 0) {
        # Select a piece:
        $_SESSION['selected'] = $action;
    }
}

if(isset($_SESSION['selected'])) {
    # Highlight the places that the piece can move:
    $highlight = validMoves(($_SESSION['selected'] - 1) % 8, floor(($_SESSION['selected'] - 1) / 8));
}

# Draw the background:
$background = imagecreatetruecolor(96, 96);
$black = imagecolorallocate($background, 0, 0, 0);
$white = imagecolorallocate($background, 255, 255, 255);
$red = imagecolorallocatealpha($background, 255, 0, 0, 100);

if(($image + floor(($image - 1) / 8)) % 2) {
    imagefilledrectangle($background, 0, 0, 96, 96, $black);
} else {
    imagefilledrectangle($background, 0, 0, 96, 96, $white);
}

# Draw a piece, if there is one:
$piece = $board[floor(($image - 1) / 8)][($image - 1) % 8];

if($piece > -1) {
    if($piece & 8) {
        $piece &= ~8;
        $draw = $front[$piece];
    } else {
        $draw = $back[$piece];
    }

    imagecopy($background, $draw, 0, 0, 0, 0, 96, 96);
}

# Should we highlight this place?
if(shouldHighlight(($image - 1) % 8, floor(($image - 1) / 8))) {
    imagefilledrectangle($background, 0, 0, 96, 96, $red);
}

header("Content-Type: image/png\r\n");

imagepng($background);

$_SESSION['board'] = $board;
?>
Ry-
quelle
Ich liebe das, aber die beiden Seiten sollten unterschiedliche Pokémon sein!
MrZander
Sehr schön. Ich mag es, dass sich der Tisch dreht, wenn sich die Drehung ändert.
Cristian Lupascu
1
Und in PHP +1 für PHP-Spiele: p
Event_Horizon
1
@hhh: Nein, Sie fügen der gleichen Seite Parameter hinzu und generieren die Bilder auf dem Server, indem Sie den RefererHeader überprüfen .
Ry
5
:-(. Ihre Sprites sind gestorben.
Justin
10

"Simon sagt" Spiel

Leider konnte ich diese Einreichung nicht rechtzeitig zum (etwas willkürlichen) Termin einreichen, aber ich wollte wirklich Animation in einem solchen Benutzerprofilspiel demonstrieren, und keine der vorherigen Einreichungen ist animiert. Dieses Spiel ist ein Klon des klassischen Milton Bradley-Spiels Simon , bei dem der Spieler versucht, eine immer längere Folge von Signalen zu wiederholen.

Informationen zu diesem Spiel, einschließlich des Quellcodes, finden Sie auf der GitHub-Seite . Es kann gelegentlich zu Grafikfehlern kommen (insbesondere auf Windows-Computern), die auf die hackige "Palettenanimation" zurückzuführen sind, die die Verwendung einer Grafikzeichnungsbibliothek überflüssig macht. Das Vorhandensein dieser Störungen kann eine nützliche Entschuldigung dafür sein, dass das Spiel aufgrund einer schrecklichen Erinnerung schnell verloren geht.

Darüber hinaus können die Auswirkungen der hohen Latenz und der begrenzten Bandbreite dieses Spiel viel schwieriger machen als das Original. Ich denke, um viel mehr als fünf Punkte zu erzielen (wenn das Spiel zum ersten Mal schneller wird), müssen Sie bestimmen, welches Licht ein Mal mehr blinkt als in der vorherigen Runde, anstatt von der richtigen Reihenfolge abzuhängen (was sehr schwierig ist) machen).

Wenn dieses Spiel für Sie nicht funktioniert (es wird jedes Mal neu gestartet, wenn Sie auf eine Schaltfläche klicken), blockiert Ihr Browser möglicherweise den Cookie. Ich habe noch keine Problemumgehung hinzugefügt. Verwenden Sie daher vorerst entweder Chrome, Opera oder Firefox oder ändern Sie vorübergehend die Cookie-Einstellungen für Internet Explorer oder Safari.

Edit 2018-05-24: Zu diesem Zeitpunkt habe ich die öffentlich zugängliche Heroku-Instanz dieser App gelöscht. Ich kann die App zu einem späteren Zeitpunkt wieder online stellen oder nicht. Der Code der App ist weiterhin auf GitHub verfügbar, sodass Sie ihn entweder lokal ausführen oder eine eigene Heroku-App-Instanz erstellen können, wenn Sie das Spiel spielen möchten.

PleaseStand
quelle
+1 Das ist absolut genial! Hätte nie gedacht , von dynamisch generierten belebtes Gifs tun: P
mellamokb
2

Schere, Stein, Papier

Alle Links gehen auf meine Profilseite, um die Geschwindigkeit zu überprüfen.

Das Spiel

timmyRS
quelle