PDA

View Full Version : گفتگو: توسعه یک بازی پازل Open Source با دلفی



zarifcomputer
دوشنبه 06 آذر 1391, 17:54 عصر
سلام به همه دلفی کاران عزیز
در این تاپیک سورس یک بازی پازل را قرار میدم تا اگه کسی از دوستان مایل بود دانلود کنه و به دلخواه خودش توسعه بده و دوباره بذاره همینجا تا بقیه هم استفاده کنند .
دوستان گرامی اگه لطف کنند و در مورد قسمت هایی که اضافه میکنند توضیحاتی هم قرار بدهند که عالی میشه و جنبه آموزشی هم پیدا میکنه .
ضمنا خوبه که در قسمت درباره نرم افزار نام و ایمیل خودتونو اضافه کنید تا اگه بازی توسعه پیدا کرد کاربران بعدی متوجه بشوند که ما حصل تلاش کدام دوستان را مشاهده می کنند
امیدوارم مفید باشه
----------------------------------------------------------------------------
توضیح لازم اینکه : این بازی یک پازل با اعداد نامرتب هست که کاربر باید اونها را مرتب کنه. خودتون دانلود کنید و ببینید.
این بازی با دلفی XE2 نوشته شده
شامل یک Form و روی این فرم ، یک Timer و یک MainMenu و یک StatusBar وجود داره و بقیه عناصر بازی RunTime ساخته میشوند .
فقط از کامپوننت های دلفی استفاده شده و انتظار میره که شما بتونید با هر نسخه از دلفی اونو اجرا کنید
در ادامه تصاویری از محیط بازی را اضافه میکنم

zarifcomputer
دوشنبه 06 آذر 1391, 17:59 عصر
این هم سورس بازی

Ananas
دوشنبه 06 آذر 1391, 21:00 عصر
سلام:قلب:.
آورین... آورین جالب بود... اوووووووه خیلیییی سخته!!! 3 در 3 رو هم نتونستم حل کنم نمی دونم کدوم بیکاری 10 در 10 هش رو حل میکنه:لبخند: البته بزرگ تر میشه راحت تر نمیشه؟ اگه راست میگی یه برنامه بنویس که بتونه معما رو بهش بدی مسیر جواب رو بگه مثلا خونه های موجود رو بهش بگی بعد بیاد بگه به ترتیب کدوم حرکت ها رو انجام بدی میرسی به جواب. می تونی بگذاریش تو قسمت منو با caption "غلط کردم" که هر کی تسلیم شد برنامه مسیر درست رو play کنه و یارو رو از عذاب در بیاره.
راستی panel ای که زیر دکمه ها هست رو رنگ تیره بگذاری بهتر میشه دید (خونه ی خالی رنگش با بقیه فرق کنه) .بعد اینکه موقع شروع تا میام دس بهش بزنم میگه برنده شدی!

zarifcomputer
دوشنبه 06 آذر 1391, 21:50 عصر
سلام
حل کردنش یه قلق خاص داره . من خودم 4 در 4 رو حل کردم .
حد اکثر 19 در 19 داره . باید به دلخواه کاربر را انتخاب کنی . اون مبحث "غلط کردم" که گفتی جالبه ولی چه فایده ای داره . خب اینطوری که دیگه بازی فکری نمیشه.
ضمنا بعد از انتخاب ابعاد بازی باید F2 را بزنی تا اعداد به هم ریخته بشن تا بتونی حسابی بازی کنی. یه بار دیگه تست کن لطفا .
راستی اگه راست میگی چرا خودت دست به کد نمیشی اون "غلط کردم" و درست نمیکنی!!!!

Felony
دوشنبه 06 آذر 1391, 21:53 عصر
آورین... آورین جالب بود... اوووووووه خیلیییی سخته!!! 3 در 3 رو هم نتونستم حل کنم نمی دونم کدوم بیکاری 10 در 10 هش رو حل میکنه
یه روش خاص داره ، بچه که بودم زیاد بازی میکردم ، الان جهت یاداوری دوران کهن 8*8 رو حدود 6 دقیقه رفتم .

Ananas
سه شنبه 07 آذر 1391, 00:22 صبح
ضمنا بعد از انتخاب ابعاد بازی باید F2 را بزنی تا اعداد به هم ریخته بشن تا بتونی حسابی بازی کنی. یه بار دیگه تست کن لطفا .
از تو منو انتخابش میکردم.

راستی اگه راست میگی چرا خودت دست به کد نمیشی اون "غلط کردم" و درست نمیکنی!!!!
من که از همون اول گفنم، نگفتم غلط کردم ولی یه چیز تو همین مایه ها:لبخند: چون شما به بازیش مسلط تر هستی بهتر می تونی برنامه ی حلال شو بنویسی.

یه روش خاص داره ، بچه که بودم زیاد بازی میکردم ، الان جهت یاداوری دوران کهن 8*8 رو حدود 6 دقیقه رفتم .
کارت درسته. فکر میکنم مربوط بشه به اولین و آخرین، شایدم بلاک وسطی، نمی دونم قلقش چیه. شبیه این باکس ه هست که همه طرفش 9 تیکس و می چرخه (اسمش یادم نیست).

zarifcomputer
سه شنبه 07 آذر 1391, 00:29 صبح
خب منم سورس را برای همین گذاشتم که همه دست برسونن ببینیم چی میشه . اگه شما هم به سورس با دقت یه نگاهی بندازی همه چیز دستگیرت میشه .
به قول قدیمیا "معما چو حل گشت آسان شود"
راستی اگه ایده های اینطوری به ذهنت میرسه بگو تا به صورت اپن سورس شروعش کنیم . برای بچه ها هم جنبه آموزشی داره. فکر کنم استقبال بشه

zarifcomputer
سه شنبه 07 آذر 1391, 18:23 عصر
اینجا کسی اهل توسعه Open Source ها نیست؟

Ananas
سه شنبه 07 آذر 1391, 21:27 عصر
میدونی چیه، راستش سخته من الان بیام کد شما رو کلی بخونم ببینم چی به چیه، شاید خودم از نو بنویسم برام راحت تر باشه! منم چند تا سورس کد گذاشتم استقبال نشد. قبول دارم که بررسی این جور کدها مخصوصا بازی ها سخته چون الگوریتم های نسبتا پیچیده ای دارن. در بعضی مواقع هم، محاسبات ریاضی میان وسط که خیلیا ندید میگن سرمون گیج رفت! سر درد گرفتیم!
اما من یک پیشنهاد دارم و فکر میکنم اینطوری برای دوستانی که به اینجا سری میزنن و دلشون میخواد چیزی یاد بگیرن (نه با مشقت) و از وقتشون هم استفاده ی مفید بکنن بهتره. من میگم اگه وقتش رو داری و یا حوصلت میاد بیا همین کدی که گذاشتی رو قطعه قطعه جدا کن و به عنوان آموزش توضیح بده به شکل گام به گام. در این بین هر کسی روش بهتری برای پیاده سازی اون قسمت داشت در موردش صحبت میکنه. این بشه یک بهونه برای تبادل اطلاعات.
ببین قبلا من تو آدرس :
http://barnamenevis.org/showthread.php?345932-Source-%D8%A8%D8%A7%D8%B2%DB%8C-Minesweeper
یک سورس بازی گذاشتم ولی به نظرم کسی نمیاد بشینه کلی فکر کنه ببینه چی کار کردم. میبیند، کدها رو هم می خونن و شاید کسایی چیزهایی هم یاد بگیرن ولی اگه من بیام ریز به ریز توضیح بدم فکر میکنم بیشتر به درد بقیه بخوره. شاید این کار رو انجام بدم.
نظرت چیه؟

zarifcomputer
چهارشنبه 08 آذر 1391, 00:09 صبح
سلام . حرفت کاملا درسته و قابل قبوله . سعی میکنم گام به گام با تصویر توضیح بدم .امیدوارم کسی علاقمند بشه .

zarifcomputer
چهارشنبه 08 آذر 1391, 00:47 صبح
از اینجا به بعد به توصیه دوست عزیز Ananas مراحل ساخت بازی را تا اینجا با تصویر شروع میکنم . هر جا سوالی پیش اومد بفرمایید تا توضیح بدم . ضمنا امیدوارم دوستان در توسعه بازی دست به کد بشوند
---------------------------------------------------------------------------------------------------------------------
1- ابتدا یک پروژه جدید ایجاد کرده و آنرا با نام های PuzzleUnit.pas و PuzzleForm و Puzzle.dpr ذخیره میکنیم
این بازی همین یک فرم را دارد .
2- روی این فرم یک MainMenu و یک Timer و یک StatusBar قرار میدهیم.
3- منوی اصلی بازی را مانند تصویر ایجاد میکنیم (تصویر اول)

95702

4- در رویداد اولین آیتم از منوی تنظیمات (ابعاد : 3 در 3) کد زیر را قرار میدهیم:
مقدار ClickCount برای نمایش تعداد کلیک های کاربر روی دکمه های بازی است
در if Sender <> nil then تعیین میشود که اگر فراخوانی این پروسیجر از طریق منوهای برنامه است ، برا اساس مقدار Tag منوی انتخاب شده محاسبات را انجام دهد و در غیر این صورت (فراخوانی از Initial) از مقدار پیشفرض منو استفاده کند
در سطر if T <> 0 then اگر یکی از منو های 3 در 3 تا 10 در 10 انتخاب شده باشد مقدار PanelRowCount := T تعیین می شود و در غیر این صورت (به دلخواه کاربر) مقدار ابعاد دلخواه کاربر از 11 الی 19 دریافت میشود
در ادامه ابعاد آرایه و پنل اصلی تعیین می شود
و در پایان ابعاد فرم و مقادیر Statusbar مشخص می گردد
و InitialPanel(P); فراخوانی می شود


procedure TPuzzleForm.N3X31Click(Sender: TObject);
var
I, T, C: Integer;
P: TPanel;
begin
ClickCount := 0;
SecondCount := 0;
Timer1.Enabled := False;
StatusBar1.Panels[1].Text := '';
StatusBar1.Panels[2].Text := '';
if Sender <> nil then
begin
T := (Sender as TMenuItem).Tag;
for I := 0 to mnuSettings.Count - 1 do
mnuSettings[I].Checked := False;
for I := 0 to mnuSettings.Count - 1 do
begin
if mnuSettings[I].Tag = T then
begin
mnuSettings[I].Checked := True;
StatusBar1.Panels[0].Text := mnuSettings[I].Caption;
Break;
end;
end;
end
else
begin
for I := 0 to mnuSettings.Count - 1 do
begin
if mnuSettings[I].Checked then
begin
T := mnuSettings[I].Tag;
StatusBar1.Panels[0].Text := mnuSettings[I].Caption;
Break;
end;
end;
end;
if T <> 0 then
PanelRowCount := T
else
begin
C := -1;
while C <> 0 do
Val(InputBox('تعداد سطر را وارد کنید', 'تعداد سطر : ', '11'), PanelRowCount, C);
if (PanelRowCount < 3) or (PanelRowCount > 19) then
begin
ShowMessage('عدد بزرگتر از 19 و کوچکتر از 3 قابل قبول نیست');
if PanelRowCount < 3 then
PanelRowCount := 3;
if PanelRowCount > 19 then
PanelRowCount := 19;
end;
StatusBar1.Panels[0].Text := 'به دلخواه کاربر : ' + IntToStr(PanelRowCount) + ' در '
+ IntToStr(PanelRowCount);
end;
PanelColCount := PanelRowCount;

SetLength(BtnsAry, PanelRowCount);
for I := Low(BtnsAry) to High(BtnsAry) do
SetLength(BtnsAry[I], PanelColCount);

P := TPanel(FindComponent('PnlButtons'));
case PanelRowCount of
3:
begin
P.Width := PanelColCount * 100;
P.Height := PanelRowCount * 100;
end;
4:
begin
P.Width := PanelColCount * 90;
P.Height := PanelRowCount * 90;
end;
5:
begin
P.Width := PanelColCount * 80;
P.Height := PanelRowCount * 80;
end;
6:
begin
P.Width := PanelColCount * 70;
P.Height := PanelRowCount * 70;
end;
7:
begin
P.Width := PanelColCount * 60;
P.Height := PanelRowCount * 60;
end;
8:
begin
P.Width := PanelColCount * 50;
P.Height := PanelRowCount * 50;
end;
9:
begin
P.Width := PanelColCount * 47;
P.Height := PanelRowCount * 47;
end;
10:
begin
P.Width := PanelColCount * 45;
P.Height := PanelRowCount * 45;
end;
else
begin
P.Width := 750;
P.Height := 550;
end;
end;
PuzzleForm.Width := P.Width + 35;
PuzzleForm.Height := P.Height + 95;
PuzzleForm.Top := Round(Screen.Height / 2) - Round(PuzzleForm.Height / 2);
PuzzleForm.Left := Round(Screen.Width / 2) - Round(PuzzleForm.Width / 2);
StatusBar1.Panels[0].Width := Round(PuzzleForm.Width / StatusBar1.Panels.Count);
StatusBar1.Panels[1].Width := Round(PuzzleForm.Width / StatusBar1.Panels.Count);
StatusBar1.Panels[2].Width := Round(PuzzleForm.Width / StatusBar1.Panels.Count);
P.Left := 10;
P.Top := 10;
InitialPanel(P);
end;




5- متغیر هایی که در کد زیر مشاهده میکنید را در قسمت مذکور تعریف میکنیم:
متغیر های PanelRowCount, PanelColCount برای نگهداری ابعاد بازی هستند
متغیر های ClickCount, SecondCount برای نگهداری تعداد کلیک کاربر و زمان سپری شده بر حسب ثانیه هستند
متغیر BtnsAry یک آرایه دو بعدی برای نگهداری ترتیب دکمه های بازی است که برای مقایسه برنده شدن کاربر پس از هر بار کلیک به کار می آید


private
{ Private declarations }
PanelRowCount, PanelColCount, ClickCount, SecondCount: Integer;
BtnsAry: Array of Array of Integer;
public
{ Public declarations }
end;


6- یک procedure با نام Initial مانند زیر ایجاد میکنیم:

procedure TPuzzleForm.Initial;
var
P: TPanel;
begin
P := TPanel.Create(PuzzleForm);
P.BevelInner := bvLowered;
P.BevelOuter := bvLowered;
P.AlignWithMargins := True;
P.Parent := PuzzleForm;
P.Name := 'PnlButtons';
P.Caption := '';
P.Color := clBlack;
N3X31Click(nil);
end;

7- یک procedure دیگر هم با مشخصات زیر ایجاد میکنیم :
کار این پروسیجر آماده سازی پنل اصلی بازی است.در این قسمت به تعداد ابعاد درخواستی کاربر که از منو انتخاب شده است کنترل TButton به صورت Runtime ایجاد شده و در پنل قرار میگیرد و در انتهای حلقه ایجاد دکمه ها آرایه عمومی بازی که قرار است به تعداد دکمه های ایجاد شده سلول داشته باشد مقدار دهی میشود . این مقدار دهی با ایجاد هر دکمه اتفاق میافتد و Tag هر دکمه که برابر با یک عدد از 1 الی تعداد ابعاد -1 است در سلول های این آرایه قرار میگیرند

procedure TPuzzleForm.InitialPanel(P: TPanel);
var
I, StartCounter, EndCounter, C : Integer;
B: TButton;
begin
StartCounter := 1;
EndCounter := (PanelRowCount * PanelColCount) - 1;
while P.ComponentCount > 0 do
P.Components[0].Free;
for I := StartCounter to EndCounter do
begin
B := TButton.Create(P);
B.Caption := IntToStr(I);
B.Parent := P;
B.Tag := I;
B.Font.Size := 10;
B.OnClick := BonClick;

B.Height := Round(P.Height / PanelRowCount);
B.Width := Round(P.Width / PanelColCount);

C := (I mod PanelColCount);

if (C > 0) and (C < PanelColCount) then
B.Left := (C * B.Width) - B.Width
else if C = 0 then
B.Left := (PanelColCount * B.Width) - B.Width;

if PanelRowCount = PanelColCount then
B.Top := B.Height * (Pred(I) div PanelRowCount)
else
begin
// در صورتیکه ابعاد بازی برابر با هم نبودند
end;
BtnsAry[(Pred(I) div PanelRowCount), (Pred(I) mod PanelColCount)] := I
end;
end;

8- برای تایمر هم کد زیر را ایجاد میکنیم :
کار تایمر پس از اولین کلیک بر روی بازی شروع میشود و هر یک ثانیه یک بار به مقدار متغیر SecondCount یک واحد می افزاید و مقدار این متغیر را در پنل یکم StatusBar نمایش میدهد

procedure TPuzzleForm.Timer1Timer(Sender: TObject);
begin
Inc(SecondCount);
StatusBar1.Panels[1].Text := 'زمان سپری شده ' + IntToStr(SecondCount) + ' ثانیه';
end;

9- در FormCreate ، Initial فراخوانی میشود

procedure TPuzzleForm.FormCreate(Sender: TObject);
begin
Initial;
end;

10- تمام آیتم های منوی تنظیمات باید رویداد اولین آیتم را فراخوانی کنند
11- و در نهایت هم کد مربوط به دکمه ها به شرح زیر تولید میشود :

procedure TPuzzleForm.BonClick(Sender: TObject);
var
A: Array of Array of Integer;
I, J, K, T, BTop, BLeft, BHeight, BWidth: Integer;
P: TPanel;
B: TButton;
S, RecordFileName: String;
IsWin: Boolean;
F: TextFile;
procedure Delay;
begin
J := 0;
while J < 2 do
begin
K := 0;
while K < 2 do
Inc(K);
Refresh;
Inc(J);
end;
end;

begin
if not Timer1.Enabled then
Timer1.Enabled := True;
Inc(ClickCount);
P := TPanel(FindComponent('PnlButtons'));
BTop := (Sender as TButton).Top;
BLeft := (Sender as TButton).Left;
BHeight := (Sender as TButton).Height;
BWidth := (Sender as TButton).Width;
SetLength(A, 3);
for I := Low(A) to High(A) do
SetLength(A[I], 3);
for I := Low(A) to High(A) do
for J := Low(A[I]) to High(A[I]) do
A[I, J] := -1;
A[1, 1] := (Sender as TButton).Tag;
for I := 0 to P.ComponentCount - 1 do
begin
B := (P.Components[I] as TButton);
if (B.Top + B.Height = BTop) and (B.Left = BLeft) then
A[0, 1] := B.Tag;
if (B.Top = BTop + BHeight) and (B.Left = BLeft) then
A[2, 1] := B.Tag;

if (B.Top = BTop) and (B.Left + B.Width = BLeft) then
A[1, 0] := B.Tag;
if (B.Top = BTop) and (B.Left - B.Width = BLeft) then
A[1, 2] := B.Tag;
end;
if (A[0, 1] = -1) and (BTop > P.Top) then
begin
A[0, 1] := 0;
for I := BTop downto BTop - BHeight do
begin
Delay;
(Sender as TButton).Top := I;
end;
end;
if (A[2, 1] = -1) and ((BTop + BHeight) < P.Height - BHeight + 10) then
begin
A[2, 1] := 0;
for I := BTop to BTop + BHeight do
begin
Delay;
(Sender as TButton).Top := I;
end;
end;
if (A[1, 0] = -1) and (BLeft > P.Left) then
begin
A[1, 0] := 0;
for I := BLeft downto BLeft - BWidth do
begin
Delay;
(Sender as TButton).Left := I;
end;
end;
if (A[1, 2] = -1) and ((BLeft + BWidth) < P.Width - BWidth + 10) then
begin
A[1, 2] := 0;
for I := BLeft to BLeft + BWidth do
begin
Delay;
(Sender as TButton).Left := I;
end;
end;
StatusBar1.Panels[2].Text := 'تعداد کلیک ' + IntToStr(ClickCount);
// بررسی مرتب بودن دکمه ها برای تعیین برنده
I := 0;
J := 0;
IsWin := True;
while I < PanelRowCount do
begin
while J < PanelColCount do
begin
for K := 0 to P.ComponentCount - 1 do
begin
B := (P.Components[K] as TButton);
T := B.Tag;
if (B.Top = (Succ(I) * BHeight) - BHeight) and
(B.Left = (Succ(J) * BWidth) - BWidth) then
begin
if BtnsAry[I, J] <> T then
begin
IsWin := False;
Break;
end;
end;
end;
if IsWin then
Inc(J)
else
Break;
end;
if IsWin then
begin
Inc(I);
J := 0;
end
else
Break;
end;
if IsWin then
begin
Timer1.Enabled := False;
ShowMessage('شما برنده شدید!!!');
S := InputBox('ثبت رکورد شما', 'لطفا نام خود ار وارد کنید', 'بی نام');
RecordFileName := ExtractFilePath(Application.ExeName) + 'BestRecords.txt';
AssignFile(F, RecordFileName);
if FileExists(RecordFileName) then
Append(F)
else
Rewrite(F);
writeLn(F, S + #9 + 'زمان : ' + IntToStr(SecondCount) + ' ثانیه ' + #9 +
'تعداد کلیک : ' + IntToStr(ClickCount) + ' دفعه ' + #9 + 'در تاریخ : ' +
DateToStr(Now) + #9 + 'ساعت : ' + TimeToStr(Now));
CloseFile(F);
end;
end;
http://barnamenevis.org/images/misc/pencil.png

Felony
چهارشنبه 08 آذر 1391, 08:09 صبح
کار خوبی کردی که داری توضیح میدی و نمیخوام ناامیدت کنم ولی با توجه به تجربه فعالیتی که اینجا داشتم چند تا مورد رو متذکر میشم :

- هیچ وقت به امید اینکه کسی تشویقت کنه یا راهت رو ادامه بده تو انجمن کار نکن که زود دلسرد میشی ، هر کسی برای خودش مشکلات و کارهایی داره که وقتش رو پر میکنه ، حتی الاف ترین آدم ، کمتر ایرانی مدیریت زمان بلده ، پس منتظر این و اون نباش .

- این نوع توضیح دادن با اینکه جای تقدیر بابت حوصله نویسندش داره ولی زیاد مناسب این انجمن نیست ، همونطور که کمتر کسی هست که کد شما رو اینجا بخونه ، کمتر کسی هم هست که این نوع آموزش رو مطالعه کنه مگر دانشجو ها و این قبیل افراد که دنبال پروژه میگیردن ، پس به نوعی داری براشون ماهی میگیری !

- بهتره متدهای اصلی برنامه رو یک توضیح کلی چند خطی بدی که هر کدوم چه کاری میکنن تا این توضیحات ریز و بی مورد ، همونطور که گفتم نباید برای کاربران ماهی بگیری ، همیشه تو پست هاتون سعی کنید توضیح کاملی به کاربر ندید و مجبورش کنید خودش هم تلاشی بکنه البته منظور این نیست که جواب کاربر رو ناقص بدید ، نه ، منظور این هست که حتی اگر جواب یک سوال رو تو یه سایت زبان اصلی براش پیدا کردید و ترجمش براتون 1 دقیقه وقت میگرفت اون متن رو ترجمه نکنید و کاربر رو به اون لینک ارجاع بدید تا خودش مجبور شه بخونه و زحمت بکشه و بفهمه مگر در مواردی خاص که مثلا ببینید با چند خط توضیح میتونید کاربر رو از خوندن چند مقاله و ... بی نیاز کنید ، اینطوری بعد از یه مدت کاربر میفهمه وقتی به یک مشکل برخورد چطور باهاش رو به رو بشه نه اینکه درجا یک تاپیک بزنه تو برنامه نویس .

- در آخر نوشتن این نوع کدها بیشتر از اینکه به فن برنامه نویسی مربوط باشه به مباحث فرعی دیگه ای مربوط میشه ( مثل ریاضیات ) ، چیزی که الان تو جامعه برنامه نویسی ما کمبودش به شدت خودنمایی میکنه پایین بودن سطح فنی برنامه نویسان هست ، به جای نوشتن این کدها و توضیح دادنشون روی یک موضوعی که فکر میکنید مفید هست و درموردش مطلب و منبع فارسی کم هست تمرکز کنید ( حتی اگر خودتون چیزی ازش نمیدونید ) و شروع به نوشتن نمونه برنامه و توضیحات براش کنید ، اینطوری هم خودتون وادار به یاد گرفتن میشید ، هم دیگران یه منبع مناسبی در اختیارشون قرار میگیره ، هم از تجربه افراد مختلف میتونید استفاده کنید ، ما هم تو همین زمین خاکی ها توپ میزدیم و میزنیم ... :لبخندساده: :

http://barnamenevis.org/showthread.php?288863

zarifcomputer
چهارشنبه 08 آذر 1391, 10:49 صبح
پس یعنی می فرمایید ادامه ندم؟
یعنی کسی اینجا این بازی را توسعه نمیده؟
باشه . نا امید نشدم .مرسی که راهنماییم کردید. سعی میکنم انرژی و زمانم رو در جهت دیگری صرف کنم.
باز هم متشکرم بابت راهنماییتون

Ananas
چهارشنبه 08 آذر 1391, 11:53 صبح
ایول حاجی. این شد. حالا تقریبا گرفتم چی کار میکنه. حالا یک راهی به ذهنم میرسه برای حل اتوماتیکی معما :
الان فرمول به هم ریختن رو جوری نوشتی که تو یک حلقه دکمه ها از هر جایی به هر جای دیگه ممکنه پرش کنن! اما اگه میومدی واقعا از بلاک خالی دکمه ها رو حرکت میدادی میتونستی تو یک لیست حرکت ها رو ذخیه کنی وبعد کاربر بیاد به عنوان استفاده از undo با فشردن ctrl+z حرکت ها رو برگرده و برسه به جواب. و هر کلیکی هم که کاربر میکنه به لیست اضافه میشه. البته موقع عقب گرد یا undo واضحه که اگه کاربر حرکتی رو ثبت کرد، undo های ذخیره شده ی بعد از اون حذف میشن و حرکت جدید ثبت میشه. گفتم "اگر کاربر حرکتی رو ثبت کرد" چون ممکنه بعد از چند تا undo حرکتی انجام نده و بخواد redo کنه و با shift+ctrl+z دوباره برگرده به آخر لیست.
یک نکته ی دیگه: اگه ما بخوایم الان بازی نوشته شده رو به شکل گرافیکی (مثلا با دایرکت ایکس یا اپن جی ال) نمایش بدیم باید کد کامپوننت های دلفی رو از کدهای اصلی بازی جدا کنیم که خودش دردسریه برای خودش! ولی اگه کل بازی تو یک کلاس جدا نوشته بشه که هیچ ربطی به vcl دلفی نداشته باشه حتی میشه کد بازی رو به c++ و یا زبان های دیگه هم تبدیل کرد. و اونوقت تو پیاده سازی انتخاب کنی که با vcl اجراش کنی یا به شکل گرافیکی.
و اگه برای اینجور کارها پایه ی سمج می خوای تو انجمن های بازی سازی بیشتر یافت میشود. تو همین سایت یا سایت های غیر از اینجا.
یه برنامه ی حرکت فنر و یک برنامه ی پرتابه هم بحثشون مدتی داغ بود یه سرس بزن به آدرسای زیر :
http://barnamenevis.org/showthread.php?351651-%D8%B4%D8%A8%DB%8C%D9%87-%D8%B3%D8%A7%D8%B2-%D8%AD%D8%B1%DA%A9%D8%AA-%D9%81%D9%86%D8%B1&highlight=%D8%AD%D8%B1%DA%A9%D8%AA+%D9%81%D9%86%D8 %B1
-------------------------------------------
http://barnamenevis.org/showthread.php?354094-%DA%A9%D9%85%DA%A9-%D8%AF%D8%B1-%D9%85%D9%88%D8%B1%D8%AF-%D8%AD%D8%B1%DA%A9%D8%AA-%D9%BE%D8%B1%D8%AA%D8%A7%D8%A8%D9%87&highlight=%D8%AD%D8%B1%DA%A9%D8%AA+%D9%81%D9%86%D8 %B1

fafa_na
چهارشنبه 06 دی 1391, 08:39 صبح
دست گلت دردنکنه ولی بابا من میخوام بدونم شخص این بازیو چطوری انجام میده.فرد برای بازی چیا را در نظر میگیره و حرکت میکنه تا برنده میشه.لطفا یکی کمک کنه لطفا

Ananas
چهارشنبه 06 دی 1391, 15:43 عصر
اول بازی باید جدول رو به هم بریزی بعد سعی کنی از بالا-چپ تا پایین-راست اعداد رو از کوچیک به بزرگ مرتب کنی.

یوسف زالی
چهارشنبه 06 دی 1391, 16:12 عصر
سلام.
کار خوبی کردی که سورس گذاشتی. خود من کمتر این کار رو می کنم!
یه راهنمایی برای حل اتوماتیک:
برای هر State یک امتیاز در نظر بگیر.
هر حرکت که حد اقل در n امین حرکت بعد از خودش بیشترین امتیاز رو بیاره حرکت غالب هست و بقیه مغلوب.
یعنی پیمایش یک درخت هرس شده با روش اول سطح تا عمق n ام.
فکر کنم واضح گفتم.
به این ترتیب برنامه با یک روند بازگشتی کنترل شده "از نظر تئوری" می تونه راهی برای برنده شدن درست کنه.
به این خاطر گفتم تا عمق n ام چون ممکنه یک حرکت باعث کاهش امتیاز شما بشه اما جا باز کنه تا در حرکت بعدی چندین امتیاز بیشتر بگیری. اگر روش رو بگذاری رو تک عمق، معمولا در Loop اسیر می شی.

zarifcomputer
پنج شنبه 07 دی 1391, 10:21 صبح
سلام به همه . اگه علاقمند هستید لطفا خودتون دست به کد بشید. عبارت Open Source به همین دلیل انتخاب شده