Помогите написать программу.
Решение задании должно садержать
1. Доказательство выигрышной стратегии для игроков
2. Реализацию игры на компьютере с соблюдением уловий
- одним игроком в игре должен быть компьютер
- начальное состояние игры, два тех игр, где оно явно не задано, должно формироваться случайным образом (случайное число выбирается из экстетического представления картинки на экране);
- после представления начального состояния, а игре должен быть запрос Кто будет ходить
первым?»;
- игра должна быть оформлена с помощью графических средств*
- игра должна иметь «Заставку» и Правила игры
- управление игрой должно осуществляться либо с помощью управляющих клавиш клавиатуры либо мышкой
- компьютер должен играть по выигрышной стратегии: либо вследствие начальных данных игры, либо, следя за ходом человека, перехватив инициативу из-за его ошибки
Игра Болтянского
Играют двое. Первый выбирает натуральное число от 2 до 9, Второй умножает это число на выбираемое натуральное число от 2 до 9, затем первый выбирает число и умножает результат на любое натуральное число от 2 до 9 и т.д. Выигрывает тот, у кого впервые получится произведение,
больше заданного положительного числа C
Выяснить при каких С существует выигрышная ситуация у первого игрока,
при каких - у второго.
помогите пожалуйста, можно и без графики
И нафига тут графика вообще, интересно.. ну, обоснование выигрышной стратегии в программу не входит.
Что-то гугл не знает про такую игру.
Со стратегией наврал я.. наверное, выигрышная стратегия состоит в домножении на "максимум", при котором противник, домножив произведение на 9 (максимальный максимум)) - не выиграет.
Так тебе с графикой надо или без? Пробовал что сделать?
> Со стратегией наврал я.. наверное, выигрышная стратегия состоит в домножении на "максимум", при котором противник, домножив произведение на 9 (максимальный максимум)) - не выиграет.
Очевидно, что нет. Игру про спички знаешь же? Каждый выбирает число от 1 до 9 и ПРИБАВЛЯЕТ к результату.
Думаешь, ты выиграешь, выбирая 9тки первую половину игры?
Вряд ли.
Почему бы и нет, наверное выиграю. Какая разница, какими шагами идти до того момента, когда можно одним ходом сгрести все оставшиеся палочки (или, домножив, перепрыгнуть число С).
Ан нет, что-то такой стратегией не удается прогу переиграть.. Что-то её вообще выиграть не получается))
Lapp, а то что твоя прога разрешает умножать на единицу - так и задумано?
Может, в этом секрет выигрышной стратегии ))
> Почему бы и нет, наверное выиграю. Какая разница, какими шагами идти до того момента, когда можно одним ходом сгрести все оставшиеся палочки (или, домножив, перепрыгнуть число С).
Ты что, игру про спички не знаешь?!
ОМБ...
Страта там такая - надо всегда дополнять кол-во оставшихся до победы элементов до кратного 10и.
короче с 5 вечера, до почти 1часа ночи пытался уловить, выйгрышную игру компа....без результатов, вот пока что получилось, комп выдает числа рандомом, и еще вывод сообщения о том кто именно выйграл кривоват. Lapp, помогите пожалуйста....
.
program boltyanskiyy;
uses crt;
var
a,b,c,p,d,winner:integer;
function isWinner(who,num,c,winner:integer):integer;
begin
if (winner = 0) and (num>=c) then begin
isWinner:=who; {1-chelovek 2-comp}
end
else begin 2
isWinner:=0;
end;
end;
begin
clrscr;
p:=1; {prisvaivaem proizvedeniuy 1}
d:=1;
randomize;
write('vvidite polozhitelnoe chislo C ( 0 - random C) = '); {zadaem C}
readln©;
if c=0 then
c:=random(1000);
writeln('chislo C = ',c);
write('kto hodit pervim?(1 - vi, 0 - komp) - '); {vibor pervogo hoda}
readln(a);
winner:=0;
if a=1 then
repeat
winner:=isWinner(1,p*d,c,winner);
writeln('vvedite chislo ot 2 do 9 - ');
read(b);
d:=random(7)+2;
p:=p*b*d;
winner:=isWinner(2,p,c,winner);
writeln('vi vveli - ',b ,', ya vvel - ',d,' proizvedenie - ',p);
until (p>=c)
else
repeat
winner:=isWinner(1,p*d,c,winner);
d:=random(7)+2;
writeln('ya vvel - ',d);
writeln('vvedite chislo ot 2 do 9 - ');
read(b);
p:=p*b*d;
winner:=isWinner(2,p,c,winner);
writeln('vi vveli - ',b,' proizvedenie - ',p);
until (p>=c);
writeln('pobedil - ',winner,',(1-chelovek, 2-komp) ');
while not keypressed do;
end.
writeln('kto hodit pervim?(1 - vi, 2 - komp)');- тут мы делаем НАОБОРОТ: если первым ходит комп, то p=TRU. Это потому, что мы сменим p при входе в цикл по ходам. Затем, перед входом в цикл мы должны присвоить начальное значение тому самому числу, которое умножается в игре. Начальное значение равно 1 (понятно, почему?) Потом в ходим в цикл. Сами ходы лучше всего оформить как подрограммы (ты с ними знаком?). Тогда описанный кусок кода будет выглядеть примерно так:
readln(a);
Player:= a=2;
n:= 1;
repeat
Player:= not Player;
if p then m:= UserMove(n) else m:= CompMove(n);
WriteLn('Игрок ',PlayerName[Player],' сделал ход ',m,', новое число равно ',n)
until n>=c;
WriteLn(PlayerName[Player],' выиграл!')
if p then m:= UserMove(n) else m:= UserMove(n);
вот щас подлатал прогу, вывод нормально работает и нормально пишит кто выйграл, комп числа выдает случайным образом, без стратегии. Можно но ли, знаяя стратегию, отредактировать мою прогу? а насчет графики....никогда не пользовался))даже не представляю как)может вы поможете сначала со стратегией??пожалуйста=)
program boltyanskiy;
uses crt;
var
a,b,c,p,d,e:integer;
flag:boolean;
begin
repeat
clrscr;
p:=1; {prisvaivaem proizvedeniuy 1}
d:=1;
randomize;
write('Vvidite polozhitelnoe chislo C ( 0 - random C) = '); {zadaem C}
readln©;
if c=0 then
c:=random(1000);
writeln('chislo C = ',c);
write('kto hodit pervim?(1 - vi, 0 - komp) - '); {vibor pervogo hoda}
readln(a);
if a=1 then flag:=true;
repeat
if flag then begin
write('vvedite chislo ot 2 do 9 - ');
read(b);
p:=p*b;
writeln('vi vveli - ',b,', proizvedenie - ',p);
end else begin
d:=random(7)+2;
p:=p*d;
writeln('ya vvel - ',d,' ,proizvedenie - ',p); end;
flag:=not flag;
until (p>=c);
if flag then writeln('Ura!Ya viygral!') else writeln('Pozdravlyayu, vi viygrali!');
write('Esche sigraem? (1 - yes, 0 - no) - ');
read(e);
until (e=0);
end.
Хорошо. Ты сделал достаточно много, чтоб я убедился, что ты умеешь работать. Но ты не выполняешь все мои просьбы, и это затрудняет разговор. Это не упрек, скорее оправдание, почему я выкладываю свой вариант. Посмотри на него и сам сделай выводы.
Обрати внимание на такие моменты..
1. Форматирование программы. Сдвиги делаются не там, где тебе кажется красивее, а по правилам. Постарайся понять их на примере моего кода. Это тебе сильно поможет в будущем при написании более длинных программ.
2. Процедуры и функции используй не только для повторяющегося кода, но и для структуризации, чтоб выделить блоки, отличающиеся по смыслу.
3. Убери CRT. Никогда не делай ClrScr без осознанной необходимости. Мне уже надоело это всем говорить, читай тут: http://forum.pascal.net.ru/index.php?s=&showtopic=26952&view=findpost&p=150391
4. Всегда старайся все числа убрать в константы. Например, тут есть числа 2 и 9. Вроде бы, они не должны меняться. На самом же деле может оказаться, когда ты придешь сдавать эту прогу препу, что он скажет: "хорошо, молодой человек, вы справились; а теперь та же задача для пределов 5 и 28..." И ты станешь ползать по всей программе, выискивая двойки и девятки..
Теперь по поводу стратегии.. Хорошо, я не буду убирать из своей проги алгоритм выигрышной стратегии. Постарайся с ним разобраться. Тебе придется это сделать, так как в задании есть вопрос: при каких С есть выигрышная стратегия. Задавай вопросы, если будет что-то неясно )).
const
d1= 2;
d2= 9;
Name: array [false..true] of string=(' I','You');
OfName: array [false..true] of string=(' My','Your');
var
c,m,n: LongInt;
Player: boolean; // false=computer, true=user
function AI: integer; // Artificial Intellect
var
d,e: LongInt;
begin
d:=c;
repeat
e:=(d-1)div n+1;
d:=(d-1)div(d2*d1)+1
until e<=9;
if e<2 then e:=2;
AI:=e
end;
function ManualMove: integer;
var
m: integer;
begin
Write('Make your move (',d1,' through ',d2,') : ');
ReadLn(m);
ManualMove:=m
end;
begin
repeat
WriteLn('Well, let''s play!');
Write('Enter the goal (0 for random) : ');
ReadLn©;
if c=0 then c:=Random(10000);
WriteLn('The goal is now set to ',c);
Write('Who moves first? 0 for computer (yes, that''s me!)), 1 for you : ');
ReadLn(m);
Player:=m=0;
n:=1;
while n<c do begin
Player:=not Player;
if Player then m:=ManualMove else m:=AI;
n:=n*m;
WriteLn(OfName[Player],' move was ',m,', the number is now ',n);
end;
WriteLn(Name[Player],' win!');
Write('Wanna play more? 0 for No, 1 for Yes: ');
ReadLn(m)
until m=0
end.
Lapp, спасибо ВАМ !вот сидел алгоритм ваш пытался понять))вышло, сразу скажу, не очень=((вот написал комментарии с коду
const
d1= 2;
d2= 9;
Name: array [false..true] of string=(' I','You');
{массиви строк, принимающие значение тру и фолс?и не понятно мне =(' I','You')}
OfName: array [false..true] of string=(' My','Your');
var
c,m,n: LongInt; {почему лонгит, а не интегер?}
Player: boolean; {false=computer, true=user}
function AI: integer; // Artificial Intellect
var
d,e: LongInt;{d-введенное с, e-ход компа}
begin
d:=c;
repeat
e:=(d-1)div n+1; {заданная длинна-1 делится на цело на текущее произведение +1}
d:=(d-1)div(d2*d1)+1 {заданная длинна изменяется, вообще не пойму для чего=(())}
until e<=9; {выполнется пока ход компа не будет в диапазоне от 2 до 9}
if e<2 then e:=2;
AI:=e
end;
function ManualMove: integer;
var
m: integer;
begin
Write('Make your move (',d1,' through ',d2,') : ');
ReadLn(m);
ManualMove:=m
end;
begin
repeat
WriteLn('Well, let''s play!');
Write('Enter the goal (0 for random) : ');
ReadLn©;
if c=0 then c:=Random(10000);
WriteLn('The goal is now set to ',c);
Write('Who moves first? 0 for computer (yes, that''s me!)), 1 for you : ');
ReadLn(m);
Player:=m=0;
n:=1;
while n<c do begin
Player:=not Player;{меняем игрока}
if Player then m:=ManualMove else m:=AI;{если плеер тру, то ходит чел, иначе комп}
n:=n*m;
WriteLn(OfName[Player],' move was ',m,', the number is now ',n);
end;
WriteLn(Name[Player],' win!');
Write('Wanna play more? 0 for No, 1 for Yes: ');
ReadLn(m)
until m=0
end.
Так. Кажется, я придумал, как объяснить эту интуицию.
См. рисунок: (масштаб пропорций не выдержан, иначе пришлось бы слишком мельчить)
Идет игра до цели C. Пусть МЫ играем проив НИХ. Игра находится в некоторой промежуточной стадии, произведение в настоящий момент равно P. Ход наш. И мы думаем то, что можем думать..
Во-первых, договоримся о терминах:
начало хода - это чему равно произведение к этому ходу;
сам ход - это на что мы домножаем (от 2 до 9);
результат хода - то, что получается после умножения начала на ход.
Например, если начало хода равно 12, а наш ход равен 3, то результат нашего хода есть 36.
Допустим, что выиграть сразу одним ходом мы не можем, потому что C слишком велико. Так вот, с самого начала ясно, что нам НЕЛЬЗЯ (если, конечно, мы хотим выиграть), чтоб результат нашего хода попал в промежуток от C/9 до C, потому что они (если они не дураки) сразу смогут выиграть. Этот ПЛОХОЙ для нас интервал изображен толстой красной линией.
Но с другой стороны, мы хотим, чтобы результат ИХ хода попал на этот участок. Желательно ЗАСТАВИТЬ их сделать такой ход. Для этого попробуем определить такой участок, любой ход с которого попадет в красный. Это сделать легко (проанализируй сам и поймешь), этот участок - от C/9/2 до C/9. Нам надо, чтобы они начинали свой ход внутри этого участка. А их начало - это наш предыдущий результат! Значит, нам надо СТРЕМИТЬСЯ попасть в этот кусок предыдущим ходом. На рисунке этот кусок изображен толстой зеленой линией.
Таким образом, мы выяснили, что нам желательно попасть ЗА число C/9/2. Другими словами, нашей ДАЛЬНЕЙ целью все еще является C, но появилась цель поближе. Назовем ее C1 (подразумевая, что то C было как бы C0). То есть, C1=C/18.
После этого мы можем абстрагироваться от дальней цели и заняться выполнением более близкой. Иными словами, теперь игра ведется не до C, а до C1. Если мы выиграем эту игру, то мы выиграем и всю игру. И мы можем повторить все те же самые рассуждения, но теперь про C1. И тогда мы найдем число C2, которое снова станет нашей новой целью. А между C2 и C1 - красный участок потоньше и зеленый участок потоньше. А за ним последкет C3 и так далее..
Так будет продолжаться до тех пор, пока текущее произведение P не попадет ЗА очередную Ci. Если оно окажется на красном куске - отлично, мы ходим так, чтобы попасть на следующий зеленый. Если нет - мы ходим как-то (при этом желательно выбрать маленький ход, чтоб затянуть игру) и хдем ИХ ошибки.
Это, так сказать, сухая теория. На практике все немного усложняется из-за того, что целые числа делятся не точно, а с остатком. Попробуй с учетом всего вышесказанного осмыслить функцию AI. Что будет неясно - задавай вопросы.
Lapp, вы гений!! столь развернутый ответ дали!как же у вас родился такой алгоритм) и все же, для меня остается не решенным вопрос том, как зависит выйгрыш компа или человека от заданного С?
Кстати, известная идея - все возможные позиции разделить на "начинающий выигрывает" и "начинающий проигрывает".
Lapp, извините!в личке баловать больше не буду)попробую разобраться с С)
И еще, не подскажете что с графикой делать?Я хочу что бы при запуске проге висела заставка:
New game
Rules
Exit
После нажатия новой игры, при ходе человека на экране появлялись 8 активных квадратикой, и на них числа от 2 до 9, что бы после нажатия на них, комп считывал это. Это вообще посильная задача?Потому что я в графике 0 =)Подскажите плиз, может статейки есть хорошие по графике в паскале?
Какая тебе нужна графика? турбо-паскалевская?
Если да, то вот тебе пример простейшей графической программы:
uses
Graph;
var
gd,gm: integer;
begin
InitGraph(gd,gm,'');
Line(0,0,GetMaxX,GetMaxY);
MoveTo(100,100);
OutText('Hi World!');
ReadLn;
CloseGraph
end.