Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Написание игр _ Scrabble

Автор: Reflex 1.11.2006 1:06

Давайте всем форумом напишем вот эту игру. Причем так, что бы в ней были режимы как одно пользовательской ( с ИИ ) так и много пользовательской игры, желательно еще и игру по локалке.
сделать все вместе согласны такой общий проект?

Автор: Vasya! 1.11.2006 2:32

Для начала что за игра опиши. Хоть в кратце. yes2.gif

Автор: Reflex 1.11.2006 2:55

Ура smile.gif smile.gif smile.gif
Появился хоть один заинтересовавшийся
smile.gif smile.gif smile.gif

http://erudit-game.net.ru/

Автор: Vasya! 1.11.2006 3:16

Типа кроссворд?

А что делать надо а то я непонял?

С чего начнем? blink.gif

Автор: Reflex 1.11.2006 3:18

Нет...
не кроссворд ...
Ну давай сначала обсудим интерфейс

Автор: Reflex 1.11.2006 4:59

или я не то понисмаю под словом кроссворд

Автор: lapp 1.11.2006 5:32

Цитата(Reflex @ 1.11.2006 1:59) *

или я не то понисмаю под словом кроссворд

Эта игра в русском варианте называется "Эрудит". Это название мне не очень нравится, слишком претенциозное. Когда-то давно (погодите.. примерно в конце 60-х - начале 70-х) ее напечатали в журнале "Наука и жизнь" под названием "Крестословица" (это мне больше по душе). Нам с сетренкой она так понравилась, что мы сделали ее на толстой фанере, клетки прожгли выжигательным прибором (им же написали ценность снизу), раскрасили маслом, вырезали фишки с буквами из твердого картона - и все это подарили маме на 8 Марта! smile.gif) Играли всей семьей вечерами.

ИИ тут не очень сложный. Главное - иметь достаточный словарь. Интерфейс же можно постараться сделать красивенький.. Правда, красивее того, фанерного, уже ничего не будет.. smile.gif

Я согласен поучаствовать в меру сил.

Автор: Reflex 1.11.2006 17:55

А ты не мог бы рассказать Алгорим ИИ? а то я что-то его не представляю

Автор: arhimag 1.11.2006 18:25

Готов помочь, предлагаю интерфейс сделать текстовый ( временно)

Автор: Vasya! 1.11.2006 22:12

Так как я в игру не играл, то тоже не знаю алгоритма. Но я надеюсь, что Андрей расскажет.

Ну вот нас уже трое!!!

Автор: Reflex 2.11.2006 5:35

ну вот что-то такое правдо это только часть.

 program scrablet;

{$APPTYPE CONSOLE}

uses
SysUtils;
type
tfield = array [0..14,0..14] of char;
const
letter_A = 1;
letter_B = 3;
letter_V = 2;
letter_G = 3;
letter_D = 2;
letter_E = 1;
letter_ZH = 5;
letter_Z = 5;
letter_I = 1;
letter_Y = 2;
letter_K = 2;
letter_L = 2;
letter_M = 2;
letter_N = 1;
letter_O = 1;
letter_P = 2;
letter_R = 2;
letter_S = 2;
letter_T = 2;
letter_U = 3;
letter_F = 10;
letter_H = 5;
letter_TS = 10;
letter_CH = 5;
letter_SH = 10;
letter_SHSC = 10;
letter_HZ = 10;
letter_II = 5;
letter_LZ = 5;
letter_EZ = 10;
letter_YU = 10;
letter_YA = 3;

type
tplayer = record
hand : array [ 0..6 ] of char;
score : integer;
put : array [ 0..6 ] of char;
puts : integer;
end;

tbag = record
plates : array [ 0..33, 0..1 ] of integer;
inside : integer;
end;

type
tgame = record
field : tfield;
player1 : tplayer;
player2 : tplayer;
bag : tbag;
end;

procedure nill_field(var field : tfield);
var i, j : integer;
begin
for i:= 0 to 14 do
for j:= 0 to 14 do
field[i,j]:='_';
end;

procedure nill_player(var player : tplayer);
var i: integer;
begin
for i:= 0 to 7 do begin
player.hand[i]:='_';
player.put[i]:='_';
end;
player.score:=0;
player.puts:=0;
end;

procedure fill_bag(var bag : tbag);
var bag_file : text;
var i : integer;
begin
assign(bag_file,'bag.res');
reset(bag_file);
for i := 0 to 33 do begin
read(bag_file, bag.plates[i,0]);
bag.plates[i,1]:=i;
end;
close(bag_file);
end;

procedure bag_move(var bag : tbag );
var i, j : integer;
begin
for i:= 0 to 32 do
if bag.plates[i,0] = 0 then
for j:= i+1 to 33 do begin
bag.plates[j-1,0]:=bag.plates[j,0];
bag.plates[j-1,1]:=bag.plates[j,1];
end;
end;

procedure hand_move(var player : tplayer);
var i,j : integer;
begin
for i:= 0 to 5 do
if player.hand[i]= '_' then
for j:= i+1 to 6 do
player.hand[j-1]:=player.hand[j];
end;

function hand_length(var player : tplayer) : integer;
var i : integer;
begin
hand_move(player);
i:=0;
while (player.hand[i]<>'_') and not(i>=6) do
inc(i);
if player.hand[6]<>'_' then
inc(i);
result:=i;
end;

procedure init_game(var game : tgame);
begin
{ fill_bag(game.bag);}
nill_field(game.field);
nill_player(game.player1);
nill_player(game.player2);
end;

procedure show_field_in_text_mode( field : tfield );
var i, j : integer;
begin
write(' ');
for i := 0 to 14 do
if (i div 10) = 1 then
write(1,' ') else write(0,' ');
writeln;
write(' ');
for i := 0 to 14 do
write(i mod 10,' ');
writeln;
writeln;
for i := 0 to 14 do begin
if (i div 10) = 0 then
write('0',i,' ') else write(i,' ');
for j := 0 to 14 do
write(field[j,i],' ');
writeln;
end;
end;

var game : tgame;
begin
init_game(game);
show_field_in_text_mode(game.field);
readln;
end.


Автор: lapp 2.11.2006 13:31

Что касается ИИ, то мне кажется, что особых проблем нет. Если есть словарь, то нужно составить из имеющихся на руках букв всевозможные сочетания, затем приставлять их к буквам на доске и сверять со словарем, что получится. Алгоритм дубовый, и работать он будет долго, но это уже второй вопрос smile.gif.

Reflex, первое и главное замечание: при совместной работе хорошо было бы иметь словесное описание как данных, так и алгоритмов. Интерфейс не является исключением. Если в лом делать отдельное описание (что я вполне понимаю), то по крайней мере все должно быть прокомментировано, и без этого никак! Хотя, я бы все же предпочел сначала обсудить..

Например, в том коде, что ты привела, в глаза бросается набор констант. Он зачем? Мне кажется, такие вещи, как ценность буквы, нужно иметь отдельно, в файлах ресурсов. Сами же буквы естественно заменить на номера, занеся их реальные значения (типа А, Б ..) в массив (который, кстати, может зависеть от выбранной кодировки). Если следовать такому плану, то игру можно сделать многоязычной: русская, английская, украинская, французская.. - смена языка производится заменой файлов. Тогда мумба-юмбафикация игры могла бы заключатся в простом добавлении файлов (словарь можно позаимствовать у Ильфа с Петровым smile.gif).

Затем, давайте договоримся о выборе стандарта языка. Я предлагаю Object Pascal, но можно и сразу на Дельфи. Суть в том, чтобы задействовать объекты - они, как известно, хороши при совместном осуществлении пректа. Чисто процедурный подход я бы не рекомендовал.. Но можно и его, если есть возражения против объектов.

Автор: arhimag 2.11.2006 16:03

В написании игр объектный подход очень удомен и многие кто пишут игры не в одиночку используют его.
Я предлагаю сразу Delphi взять. А по устройству хранения фишек, то согласен с lapp так будет лучше. Пока про ии не очень представляю как это оссуществить. Предлагаю сначала написать человек-человек а потом уже извращаться типа локалки и ИИ.

Автор: Michael_Rybak 2.11.2006 16:53

Цитата
Если есть словарь, то нужно составить из имеющихся на руках букв всевозможные сочетания, затем приставлять их к буквам на доске и сверять со словарем, что получится. Алгоритм дубовый, и работать он будет долго, но это уже второй вопрос smile.gif.


Алгоритм не дубовый, и он будет летать. Только лучше, наверное, сначала смотреть, куда будем ставить, а потом уже ставить.

На поле 15х15 всего 225 клеток. От каждой клетки пытаемся проложить слово вправо, и слово вниз.

Пусть словарь у нас отсортирован лексикографически, и пусть в нем n слов. У нас есть клетка на доске, и мы идем от нее вправо. Хотим получить список всех возможных слов (учитывая, хватит ли у нас фишек, чтоб достроить недостающие буквы).

Рекурсивный перебор такой:

Сначала считаем, что нам подходят все слова: [0; n). Смотрим на первую букву (т.е. на начальную клетку). Если там уже стоит фишка с буквой, скажем, К, то нас уже устраивает не [0; n), а [x; y), где x - первое слово на букву К, а y - первое слово на букву Л. Если же там - пусто, то пытаемся туда поставить одну из букв, имеющихся на руках (всего их 7?). И опять-таки, сужаем интервал соответственно. И теперь рекурсивно переходим ко второй букве. Опять, если там не пусто, сужаем интервал однозначно, если же пусто - перебираем и сужаем, и т.д.

Поскольку на каждом шаге, решения относительно всех предыдущих букв уже приняты, то каждый раз нам всегда нужно рассматривать только слова из текущего интервала (все остальные не подходят под уже построенное).

Используя префиксное дерево, мы будем сужать интервалы за O(1), и перебор будет работать неприлично быстро smile.gif

Эту часть могу взять на себя.

Автор: lapp 2.11.2006 17:37

Цитата(Michael_Rybak @ 2.11.2006 13:53) *

Только лучше, наверное, сначала смотреть, куда будем ставить, а потом уже ставить.
..
Эту часть могу взять на себя.

Да, так, конечно, лучше, особенно учитывая, что возможно составление слова из нескольких частей, типа:
САМОЛЕТ
- черные буквы уже стояли, а красные мы поставили.
На руках 7 фишек, да (насколько я помню).

Можешь - хорошо. Вполне можно все делать параллельно, только нужно бы договориться о стандарте данных.

Автор: lapp 2.11.2006 18:11

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

{Scrabble}
{Version Text Object Pascal 0.01}
{File Scrabble_TOP-0_01}

const
BoardSize=15; BrdSz=BoardSize; N=BoardSize; {Razmer doski}
MaxAlphaLength=100; MxAL=MaxAlphaLength; {Max dlina alfavita}

type
tLetter=word; {Nomer bukvy po poryadku, nachinaya s 1}
tCell=record {Yacheika doski}
Letter:tLetter; {bukva}
Bonus:integer; {umnozhenie ceny}
end;
tBoard=array[1..BoardSize]of tCell; {Doska}
tRate=array[1..MaxAlphaLength]of integer; {Cena kazhdoi bukvy}
tAlpha=array[1..MaxAlphaLength]of char; {Alfavit, simboly dlya vyvoda}

var
Board:tBoard;
M:word; {Dlina alfavita, schityvaem is faila}
Rate:tRate; {Schityvaem is faila}
Alpha:tAlpha; {Schityvaem is faila}

begin
end.

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

И еще одно замечание про ИИ. Судя по словам Michael_Rybak'а, у человека будет слишком мало шансов выиграть. Кроме того, Игра довольно существенно многосторонняя, то есть рассчитана на 2 и больше игроков, причем по опыту я знаю, что играть втроем интереснее, чем вдвоем, а оптимум, намерное, четыре. Так что центр тяжести следует сместить все же в сторону интерфейса для сетевой игры.
Как вы думаете?

Автор: Michael_Rybak 2.11.2006 18:45

Цитата
у человека будет слишком мало шансов выиграть.

Тут у меня есть 2 соображения. Во-первых, понятно, что можно уровни сложности ввести. А во-вторых, можно показывать игроку все возможные слова, чтоб он только выбирал. Тогда комп (с жадным алгоритмом) будет проигрывать, потому что игрок сможет хоть как-то продумывать наперед. А игра получит приципиально другой характер smile.gif

Цитата
Так что центр тяжести следует сместить все же в сторону интерфейса для сетевой игры.


*Всю* сетевую часть, мне кажется, должен делать один (опытный в этом) человек, и тогда проблем не будет. А интерфейсы, конечно, заренее надо. И без объектов, имо, жутко такое писать. И сетевую часть, и вообще всё.

Еще хорошо бы code conventions.

Автор: arhimag 2.11.2006 19:36

как - то давно вы мне давали чат по локалке, и я от туда вынес много чего-то умного. Так вот я предлагаю взять сделать чат, потом добавить функцию перебегающего сервера, тоесть тот кто открывает комнату чата у того в тойже проге и работает сервер. И дальше передавать сообщения типа:
"Player <1> <22><in>(<0>,<12>)" и их расшифровывать пример означает: игрок 1 поставил букву 22 в клетку 0,12. впринципе я все это могу реализовать, кроме одного я не могу реализовать поиск уже созданных игр

Автор: Michael_Rybak 2.11.2006 20:50

Еще, если уж на то пошло, то давайте кто-то начнет проект на sf, tigris или еще где. И будет принимать главные решения относительно структуры, конвенций, распределения обязанностей. Имо, без version control гиблое дело, собирать по кускам по 100 раз. А так - весело будет.

Автор: lapp 3.11.2006 5:30

Цитата(arhimag @ 2.11.2006 16:36) *
я предлагаю взять сделать чат, потом добавить функцию перебегающего сервера,
...
кроме одного я не могу реализовать поиск уже созданных игр

Мое мнение, не стОит делать самостоятельный сетевой уровень, по крайней мере сейчас.
Предлагаю для начала воспользоваться web-сервером. Сделать простейший CGI..
Я готов предоставить страничку на своем сайте ради такого дела smile.gif. Правда, может возникнуть сложность с исполняемым кодом.. Не помню, Linux там или BSD.. проверю. Если не сложится там - все равно найдем, где.
Цитата(Michael_Rybak @ 2.11.2006 17:50) *

давайте кто-то начнет проект на sf, tigris или еще где.
...
- весело будет.

Ты слыхал о принципе наказуемости инициативы? smile.gif Можешь заняться..
Если серьезно, я пока не уверен, что это действительно нужно. Давай дождемся реальной необходимости. Иначе нетрудно утонуть во всем этом, не начав..
А весело и так будет! smile.gif

Reflex, ты где? что молчишь?

Автор: Michael_Rybak 3.11.2006 5:36

Цитата
Давай дождемся реальной необходимости.


ОК smile.gif
Но если что - без проблем.

Автор: lapp 3.11.2006 18:14

Наткнулся на неожиданное препятствие: неизвестно, сколько должно быть каточек с каждой буквой. Поверхностный поиск в Инете пока ничего не дал. Можно, конечно, самим прикинуть приблизительно..

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

Еще масса интересной ифы. Вот, например (взято http://lib.proza.com.ua/book/449):

Цитата
Скрабл. Набоков в романе "Ада" воспел мистические свойства этой игры. (Например, выпадает набор букв, которые маленькая Люсетта складывает в р-о-т-и-к плюс не приспособленная к делу "л", а ее неневинные сестра и кузен фавнически хохочут.) Не так уж много я играла в скрабл, но "рай" и "ад" складывались у меня многозначительным до безвкусия кроссвордиком раз так семнадцать. (Набоков употреблял слово крестословица. А в советском варианте скрабл именовался игрой "Эрудит".)
Случай, достойный именно "Эрудита". Человек, некто Костя Богомолов из Екатеринбурга, безнадежно проигрывал всем, включая детей и иностранцев. Потом составил слово "икт", значения которого не помнил. Из жалости к аутсайдеру посмотрели в словаре - и нашли там слово "икт". Оно обернулось неким термином, относящимся к стихосложению (точно не помню). Так вот, поскольку этот "икт" утроился, пройдя через красный квадратик, и прицепил еще по дороге какие-то более или менее очевидные слова вроде "ют", которые тоже удваивались и утраивались, Костя Богомолов набрал разом такую кучу очков, что всех нагнал и в итоге, кажется, выиграл.
Подробность достойная адского скрабла: практически в каждой игре у нас возникает слово "вонь". И тут же начинает слегка припахивать серой.
А еще моему сыну Мите раз так семь подряд выпадали буквы в-ы-м-я. И за всю игру ему так и не удалось пристроить это "вымя" к общему кроссворду. Причем значения этого слова он, как выяснилось, не знал. Но все равно кричал: "У меня вымя опять!".
Однажды с нами играла его учительница рисования, девушка тонная, культурная. Получалось у нее плохо. "Что, опять пропускаете ход? Да вот же, Лена, хорошее слово, сказал Митя, заглядывая к ней через плечо, - г-о-в-н-о. Прямо по порядку у вас и лежат". Действительно, буквы лежали на зеленой пластмассовой жердочке строго в неприличном порядке, но ей просто не приходило в голову, что такое - может быть словом.
А ведь это тоже было послание. Хотя до креста, где рай пересекается с адом, конечно, не дотягивает. Просто маленькое шуточное послание.
Вот Кайоль, девушка совсем даже не-тонная, играет всегда превосходно, хотя русскому языку практически и не училась. Она даже составила как-то раз слово к-а-ч-е-н-к-о (то же самое, что дурдом). Еще пыталась впарить слово "зись", утверждая, что у них в школе-студии МХАТ был такой предмет, очень серьезная наука, старенький такой дяденька читал лекции, зачет потом сдавали, спросите Марьяшу Шульц или Олесю Поташинскую, они подтвердят.
Спросили. Оказалось, что предмет был - эстетика, а Зись - фамилия преподавателя.
Отдельное удовольствие - играть в слова с детьми, которые еще не умеют читать-писать.
Мой единоутробнейший сынок Митя, опять-таки, придумал игру "охота на зверей". Это нечто вроде "морского боя", но вместо абстрактных одноклеточных, двухклеточных, трехклеточных кораблей в квадраты вписываются конкретные звери. "Раненая" буква рассекречивается.
Постепенно выяснилось, что на Митином поле пасутся следующие звери: к-р-о-л-ь-и-к, л-ь-и-с, в-о-р-к, трогательно-избыточный з-а-й-е-т-с, лаконичный с-о-б-к, а также с-е-л-ь-о-т, объясненный как муж селедки. Еще - з-а-г. "-А это-то кто?" - "- Заг? Ты что, не знаешь? Такая птица. Высотой - сто метров. А длиной - два метра". Подумал и добавил: "Чистая, культурная птица".
Для этого, собственно, и стоит убивать долгие зимние вечера не занимаясь чем-то полезным (видео, секс, вязание, самообразование), а за бессмысленными и неазартными настольными играми. Чтобы узнать и полюбить его, - зага. Чистую, культурную птицу.

То, что ниже, добавлено позже.
Нашел все же нормальное описание, вот тут: http://detochka.ru/game/equip/scrabble/.
Ну и добавил-подправил бервый блин..
Нижеследующий код рисует поле, где, как и полагается, разными цветами обозначено удвоение/утроение букв/слов. Доска почти готова к игре smile.gif. Но вот, что я выяснил при ее просмотре: так играть нельзя. Слишком мелко. А как укрупнить - неясно. Всякие комбинации символов выглядят не здорово.. Так что придется все же перебираться в графику, думаю.
Программа читает файл scrabble.dat, который присовокуплен ниже (количество карточек в нем пока неверное).
Написано на Object Pascal в расчете на будущее (хотя пока том от объектов толку ноль).
{Scrabble}
{Version T.P.00.02}
{File Scrabble_TOP-0_02}
{Date 061103}

uses
CRT;

const
Version=11002;
FileSign='Scrabble Forum-Pascal Project';
DataFile='Scrabble.dat';
MaxBoardSize=100; MxBS=MaxBoardSize; {Max Razmer doski}
MaxAlphaLength=100; MxAL=MaxAlphaLength; {Max dlina alfavita}
BonusColors:array[0..15]of byte=(0,7,1,2,0,0,0,5,4,0,0,0,0,0,0,0);


type
tLetter=word; {Nomer bukvy po poryadku, nachinaya s 1}
tCell=object {Yacheika doski}
Letter:tLetter; {Nomer bukvy, 0-pusto}
Bonus:integer; {umnozhenie ceny (cvetnye kletki)}
procedure Show;
procedure Hide;
end;
tBoard=object {Doska}
Field:array[1..MxBS,1..MxBS]of tCell; {Kletki - Horizontal,Vertical}
Nx,Ny:integer; {Razmery doski}
x,y:integer; {Koordinaty levogo-vrhnego ugla}
sx,sy:integer; {Shagi po x i y}
constructor Init;
procedure Show;
procedure Hide;
end;
tToken=record
Rate:integer; {Cena bukvy}
Symbol:char; {Symvol dlya pokaza na doske}
Quantity:integer; {Kolichestvo bukv}
end;
tAlpha=array[1..MaxAlphaLength]of tToken; {Alfavit}

var
Board:tBoard;
M:word; {Dlina alfavita, schityvaem is faila}
Alpha:tAlpha; {Schityvaem is faila}

Data:text;


procedure tCell.Show;
begin
TextBackground(BonusColors[Bonus]);
if Letter<>0 then Write(Letter) else Write(' ');
end;

procedure tCell.Hide;
begin
Write(' ')
end;

constructor tBoard.Init;
var
i,j:integer;
begin
x:=3; y:=3;
sx:=1; sy:=1;
for j:=1 to Ny do for i:=1 to Nx do;
end;

procedure tBoard.Show;
var
i,j:integer;
begin
for j:=1 to Ny do for i:=1 to Nx do begin
GoToXY(x+sx*Pred(i),y+sy*Pred(j));
Field[i,j].Show
end
end;

procedure tBoard.Hide;
begin
Write(' ')
end;

var
i,j:integer;
c:char;

begin
Board.Init;
Assign(Data,DataFile);
ReSet(Data);
ReadLn(Data);
ReadLn(Data);
with Board do begin
ReadLn(Data,Nx,Ny);
for j:=1 to Ny do begin
for i:=1 to Nx do with Field[i,j] do begin
Read(Data,c);
if c='.' then Bonus:=1 else Bonus:=Ord©-48
end;
ReadLn(Data)
end
end;
ReadLn(Data);
ReadLn(Data);
ReadLn(Data,M);
for i:=1 to M do with Alpha[i] do repeat Read(Data,Symbol) until Symbol<>' ';
for i:=1 to M do begin
Read(Data,Alpha[i].Rate);
end;
for i:=1 to M do Read(Data,Alpha[i].Quantity);
Close(Data);

ClrScr;
Board.Show;
ReadLn
end.

Scrabble Forum-Pascal Project
11001
15 15
8..2...8...2..8
.7...3...3...7.
..7...2.2...7..
2..7...2...7..2
....3.....3....
.3...2...2...3.
..2.........2..
8..2.......2..8
..2.........2..
.3...2...2...3.
....3.....3....
2..7...2...7..2
..7...2.2...7..
.7...3...3...7.
8..2...8...2..8
russian
win1251
32
А Б В Г Д Е Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я
1 3 2 3 2 1 5 5 1 3 2 2 2 1 1 2 2 2 2 3 10 5 10 5 10 10 10 5 5 10 10 3
12 7 9 7 9 12 5 5 12 7 9 9 9 12 12 9 9 9 9 7 3 5 3 5 3 3 3 5 5 3 3 7


Автор: Reflex 4.11.2006 15:09

Привет всем, я просто даувно не была в интернете. а переходить на Graph помоему бессмысленно, тогда уж делать на формах...