Создать мини-игру профиля пользователя


49

Вчера я наткнулся на очень умную вещь.

Tic-Tac-Toe профиль игры Minitech

Да, это рабочая реализация Tic-Tac-Toe на странице профиля пользователя, с @minitech. Конечно, в тот момент, когда я это увидел, мне пришлось перепроектировать его идею и превзойти его : P

Mellamokb в Ханое профиль игры

Вот мой собственный пример, встроенный прямо в пост. Это немного глючит из-за пары деталей реализации, для которых я не разработал хорошее решение. Иногда после того, как вы нажимаете на колышек, он не обновляется должным образом, пока не обновится другая страница:

Башни Ханоя

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

Сброс

Вы можете сделать лучше?

  • Создайте рабочую игру в своем опубликованном ответе (или на странице своего профиля пользователя). Это делается путем соответствующей настройки вашего веб-сервера (или написания программы, которая действует как веб-сервер) и встраивания содержимого из него в сообщение с помощью реферера, чтобы определить, какие команды пользователь дает игре.
  • Самая крутая идея (большинство голосов) побеждает в конкурсе ко Дню Канады (воскресенье, 1 июля 2012 г., 23:59 EST)
  • В случае ничьей побеждает более старый ответ.

1
+1 Простая, но блестящая идея! BTW - для срока я думаю , что вы имеете в виду июня 2, 2012.
Cristian Lupaşcu

Сумасшедший, да, я сделал, спасибо :)
mellamokb

1
@boothby: я действительно думал об удалении своего ответа. Намерение состояло в том, чтобы привести конкретный пример, а не выиграть конкурс (или голоса, меня не очень заботит репутация). Можете ли вы дать некоторые конструктивные предложения для конкурса? Каким вы хотите, чтобы срок был? Как изменить спецификацию, чтобы мотивировать вас на участие?
mellamokb

4
Я только что заметил, что ИИ Minitech не может играть в идеальную игру в крестики-нолики. Игровой центр, нижний левый, верхний центр, правый центр, левый центр.
PhiNotPi

1
@ Mr.Wizard: отлично работает на FF 12.0 и Windows 7, не могли бы вы опубликовать более подробную информацию о том, что не работает?
ChristopheD

Ответы:


27

Игра жизни Конвея

+1 поколение - +5 поколений - увеличить - уменьшить

Схема загрузки: случайная - планер - оружейная звезда - улитка - lwss - lightpeedoscillator1 - тумблер

Используется выход Python и SVG. Сначала я попытался использовать отдельные пиксели (чтобы вы могли переключать отдельные ячейки), но это не сработало, потому что браузер не загружает изображения по порядку. Кроме того, гораздо больше шаблонов возможно, как это без сбоя моего веб-сервера.

Обновить:

Я немного повеселился с python и добавил несколько функций и улучшений:

  • Добавлен HUD с подсчетом населения, увеличением и именем
  • Шаблоны в формате rle теперь можно загружать ( длинный список , через ) с помощью patternпараметра (например ?pattern=glider). Размер файла ограничен 1,5 КБ
  • Можно переслать n поколений, ограниченных до 5, используя nextпараметр
  • Немного улучшен алгоритм. Это не очень быстро, хотя, я хочу, чтобы это было просто
  • Теперь он также работает автономно (использует как referer, так и собственную строку запроса): 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()

Вы можете взять мой код в качестве шаблона для дальнейшей подачи в python fastcgi.


+1 Круто! Одно предложение: добавляйте #5946свои ссылки, и они будут переходить к вашему сообщению после каждого обновления.
mellamokb

хм .. по крайней мере это сработало, когда я попробовал .. ах. потому что в Towers of Hanoi вы всегда нажимаете на разные колышки. хмм
mellamokb

@mellamokb это работает, но вы не можете дважды щелкнуть одну и ту же ссылку
скопируйте

Я только что понял, что лол. Думаю, вы можете предоставить заявление об отказе от ответственности, что при следующем поколении просто нажмите F5 для будущих итераций, а не нажимайте nextссылку снова и снова после первого раза.
mellamokb

1
@ mellamokb спасибо. По моему мнению, вам не нужно принимать ответы на этой платформе, потому что похоже, что задача закрыта
скопируйте

35

C # - стек обмена палач

Угадайте названия веб-сайтов Stack Exchange в этой игре Hangman:



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


Это было сделано с использованием ASP.NET MVC 3.0 . Вот код, Controllerкоторый делает трюк:

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;
    }
}

Кроме этого кода, есть еще три класса, которые я не включил, так как они довольно длинные и простые:

  • HangmanGame - здесь реализованы правила игры
  • HangmanImageRenderer - класс, который заключает в себе все уродство GDI
  • ImageResult- пользовательский, ActionResultкоторый используется для возврата динамически сгенерированного изображения

Полный список кодов доступен по адресу http://pastebin.com/ccwZLknX.


+1 Вау, ребята, вы классные :). Понравились идеи до сих пор!
mellamokb

Круто, никогда не слышал о appharbor.com. Вы действительно платите, чтобы разместить свой ответ?
mellamokb

@mellamokb нет, я использую план бесплатного хостинга Appharbor. Если на это нажали много, я думаю, мне придется заплатить, хотя ... :)
Кристиан Лупаску

2
Я собирался упомянуть, если необходимо, я могу предоставить собственный хостинг поддоменов и FTP доступ к моему хостинг-сайту.
mellamokb

@mellamokb спасибо, но я думаю, что этот хостинг подойдет. Я просто шутил о многих кликах. :)
Кристиан Лупаску,

19

Clojoban! [НЗП]

Я хотел сделать из этого игру побольше, чтобы выучить Clojure , так что это заняло некоторое время (и получилось довольно масштабно). Мне было очень весело делать это, кстати!

Clojoban! Restart levelNew game

, ,

- No-op*

, ,

** (нажмите здесь, если игра перестает отвечать на запросы) *

инструкции

Вы Робби Robby, трудолюбивый робот. Вы работаете в качестве FlipCo Industriesперевозчика тяжелых грузов. Ваша задача состоит в том, чтобы перевести каждый box Коробкана goal Цельрасходы как можно меньше шагов. FlipCoОбъекты ОПАСНЫ . Есть много проблем и специальных мест для открытия.

Если вы застряли, нажмите Restart level(но ваш счетчик шагов не будет сброшен!)


Вы также можете поиграть на главной странице Clojoban (хотя это как бы разрушает цель задачи). Это решает печально известную проблему привязки, не требует межсайтовых куки-файлов и вы можете играть с клавишами со стрелками на клавиатуре! Вы также можете играть на моей странице профиля пользователя без назойливой проблемы с привязкой.

В Firefox изображение не мерцает во время загрузки, поэтому играть немного удобнее.

Эта игра далеко от завершения, Clojoban все еще в стадии разработки . Вы можете увидеть полный исходный код на странице проекта Clojoban's GitHub . В README есть некоторая информация о содействии . Мне тоже нужны уровни! Смотрите формат уровней на примерах уровней . Вы можете заглянуть в систему отслеживания проблем Clojoban и посмотреть, что будет дальше!


Теперь ваша репутация 11 :)
mellamokb

@ mellamokb спасибо! Игра встроена сейчас :)
Альваро Куэста

Видимо, это не привлекло много внимания. Любые советы по улучшению?
Альваро Куэста

Ваш ответ хороший, я думаю, что этот вопрос в целом застоялся. Я не видел много активности или голосов за последние пару дней.
mellamokb

Это отличная игра! Я думаю, что вы должны сделать отдельную версию; Я добрался до третьего уровня и избавился от нажатия кнопки No-op. :) В любом случае, отличная работа!
Кристиан Лупаску

17

Лабиринт

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

Я начал с генератора лабиринтов PHP, который нашел здесь: http://dev.horemag.net/2008/03/01/php-maze-generation-class/ .

РЕДАКТИРОВАТЬ : изменил вывод на PNG вместо SVG (для лучшей кросс-браузерной совместимости).

РЕДАКТИРОВАТЬ 2: добавлен заголовок для исправления совместимости IE cookie. Теперь должен корректно работать во всех основных браузерах.

Изображение не обновляется, если вы берете одно и то же направление дважды (из-за якорных ссылок). Нажмите F5 во второй раз, или запустите лабиринт в моем профиле stackoverflow .

РЕДАКТИРОВАТЬ 3: Добавлена ​​кнопка «без операции», чтобы можно было легко двигаться в одном и том же направлении дважды (см. Комментарии ниже).

<?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);
?>

1
+1 Здорово! для лучшего опыта, добавьте #answer-6171в конце своих ссылок. Иначе ни у кого не хватит терпения разгадать лабиринт.
Кристиан Лупаску

@ W0lf: Спасибо. Я думал о включении #ссылок, но проблема в том, что они не обновляют страницу, когда вы идете в одном и том же направлении дважды (что может случиться в лабиринте ;-). Я добавил их сейчас, чтобы людям приходилось нажимать F5 во второй раз, когда они хотят пойти в том же направлении. Другой вариант - сыграть здесь (мой SO-профиль: stackoverflow.com/users/81179/christophed )
ChristopheD

Я хотел бы представить простую ссылку без операции (обновить?), Чтобы упростить обновление при попытке дважды двигаться в одном направлении :)
kaoD

@kaoD: Без якорных частей ( #), которые переходят к правильному ответу на вопрос (внутренне, без обновления страницы), простое обновление страницы будет работать нормально (как вы можете видеть в моем связанном профиле, где также доступен тот же лабиринт) , Но проблема тогда будет в том, что вы окажетесь в верхней части страницы после каждого обновления. Настоящая проблема в том, что мы действительно ограничены в том, что мы можем включить в ответ здесь, на StackOverflow (по уважительной причине, конечно), мы не можем использовать произвольный Javascript, например. Я понятия не имею о простом выходе.
ChristopheD

У вас все еще может быть привязка, и она будет идти прямо к вашему сообщению, но с другим URL-адресом (который обеспечит правильный игровой процесс.) Я считаю метод F5 неуклюжим.
КаоД

14

Шахматы для покемонов на 2 игрока [работа в процессе]

Потому что так веселее. Придет однажды: AI, изометрическая сетка и тени!

http://minite.ch/chess/?i=1 http://minite.ch/chess/?i=2 http://minite.ch/chess/?i=3 http://minite.ch/ шахматы /? 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/ шахматы /? 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/ шахматы /? 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

Извините, не пассивен и не рокирован. Мат / проверка / обнаружение патовой ситуации должно быть реализовано. Спрайты отсюда: http://floatzel.net/pokemon/black-white/sprites/

Вот источник:

<?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;
?>

Я люблю это, но обе стороны должны быть разными покемонов!
MrZander

Очень хорошо. Мне нравится, что стол поворачивается всякий раз, когда меняется ход.
Кристиан Лупаску

1
А в PHP +1 для игр PHP: p
Event_Horizon

1
@hhh: Нет, вы добавляете параметры на одну и ту же страницу и генерируете изображения на сервере, проверяя Refererзаголовок.
Ry-

5
:-(. Ваши спрайты умерли.
Джастин

10

Игра "Саймон говорит"

К сожалению, я не смог вовремя получить это представление к (несколько произвольному) сроку, но я действительно хотел продемонстрировать анимацию в такой игре с профилем пользователя, и ни одно из предыдущих представлений не было анимированным. Эта игра является клоном классической игры Милтона Брэдли Саймон , в которой игрок пытается повторить все более длинную последовательность сигналов.

Информация об этой игре, включая ее исходный код, доступна на странице GitHub . Могут быть случайные графические сбои (особенно на компьютерах с Windows), возникающие из-за хакерской «анимации палитры», которая устраняет необходимость в библиотеке графических рисунков. Наличие этих глюков может послужить полезным оправданием для быстрой потери этой игры из-за ужасной памяти.

Кроме того, эффекты высокой задержки и ограниченной пропускной способности могут сделать эту игру намного более сложной, чем оригинал. Я думаю, что для того, чтобы получить гораздо больше, чем пять очков (когда игра в первый раз ускоряется), вам нужно будет определить, какой свет мигает больше, чем в предыдущем раунде, а не в зависимости от правильной последовательности (что очень трудно делать).

Если эта игра не работает для вас (она перезапускается каждый раз, когда вы нажимаете кнопку), возможно, ваш браузер блокирует его cookie. Я еще не добавил обходной путь, поэтому в настоящее время, пожалуйста, используйте Chrome, Opera или Firefox или временно измените настройки файлов cookie Internet Explorer или Safari.

Изменить 2018-05-24: в настоящее время я удалил общедоступный экземпляр Heroku этого приложения. Я могу или не могу вернуть приложение в сеть позднее. Код приложения по- прежнему доступен на GitHub, поэтому вы можете запустить его локально или создать свой собственный экземпляр приложения Heroku, если вы хотите играть в игру.


+1 Это просто великолепно! Никогда не думал о том, чтобы делать динамически генерируемые
анимационные

2

Камень ножницы Бумага

Все ссылки идут на страницу моего профиля для скорости.

Игра

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.