نمایش نتایج 1 تا 16 از 16

نام تاپیک: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

  1. #1

    بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری


    $w0=10;
    $w1=50;
    $w2=-30;
    $v=$w0+($w1*$x1)+($w2*$x2);

    if($a['sotoon'.$i]["kh".$j]===2)
    {

    if(isset($a['sotoon'.($i+1)]["kh".($j+1)]))
    {
    if($a['sotoon'.($i+1)]["kh".($j+1)]===0)
    {
    $a['sotoon'.$i]["kh".$j]=0;
    $a['sotoon'.($i+1)]["kh".($j+1)]=2;

    }
    }


    }


    اجازه بدین من کلا بگم هدف چیه
    تا شما دوستان با توجه به اطلاعاتتون به من خنگ کمک کنید از دستم راحت شید
    من همه کد قبلیا را پاک کردم
    الان این را دارم

    ببینید
    این بازی چکرز برای درس یادگیری طبق الگوریتم minmax با عمق یک
    چیزی که من فهمیدم اینه در هر لحظه
    نوبت هرکی هست
    باید بیایم از دیدگاه اون تمام حرکت های ممکن را برسی کنیم
    به ازای هر حرکت جدید یه v داریم v ارزش صفحه بازی هست
    v های جدید را با v قبلی مقایسه میکنیم
    اگر v جدیدی نبود و تمام v های بدست اومده با v قبلی برابر بود
    رندوم یکیشو انتخاب میکنیم و حرکتشو انجام میدیم
    اگر v جدید داشتیم میایم vجدید را از v قدیم کم میکنیم یه مقداری بدست میاریم که میشه error
    حالا طبق این فرمول w ها را تغییر میدیم
    wجدید=wقدیم +0.1*تعداد مهره های همون w * مقدار errror
    مثلا برای w1 تعداد مهره های 1 میشه همون x1 در واقع میشه تعداد خانه هایی که مقدار یک دارن
    تا جایی انجام میدیم که مقدار v بشه 100 یا -100 یا 0
    این همه آن چیزی بود که باید بنویسم
    من اینجوری گفتم
    گفتم با اون دوتا حلقه for تو در تو میام به هر خانه دسترسی پیدا میکنیم
    بعد مثلا نوبت شماره های 2 است
    تمام حالت هایی که 2 بتونه انجام بده را در نظر میگیریم
    شما فرض کنید شماره دو فقط در صورتی که خونه سطر بعد و ستون بعدش 0 باشه میتونه بره در آن خانه قرار بگیرد که در این صورت خودش مقدارش میشه 0 خونه سطر بعد و ستون بعدش میشه 2
    (که من حتی این حرکت را نمیتونم بنویسم خودش میشه صفر ولی دوتا خونه سطر بعد و ستون بعدش میشه2 )
    الان باید بیام به ازای هر خونه ای که میتونه این حرکت را انجام بده بیا v راجدا حساب کن با v قبلی مقایسه کن
    و
    ...
    الان اگر درست فهمیده باشم باید اول توی اون دوتا حلقه for تو در تو تمام حرکات ممکن برای مثلا مهره های 2 حساب کنم بزارم توی تابع
    همونجا باید فرمول v را هم حساب کنم و مقایسه را انجام بدم
    ولی من حتی نمیتونم تابع حرکت را بنویسم
    خواهشا کمکم کنید
    اگرم به نظرتون نشدنیه بگین لطفا
    ممنون میشم

  2. #2

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

    میگم من یه چیزی بگم
    آقای ali_sed
    اگر بخواهیم دقیقیا طبق هر چیزی که شما لطف کردین و گفتین پیش بریم
    آیا میشه بعد از اون دوتا حلقه foreach به مقدارهای سطر بعد و ستون بعد دسترسی پیدا کرد

    <?php
    $a=array(
    array(2,5,2,5,0,5,1,5,),
    array(2,5,2,5,0,5,1,5,),
    array(2,5,2,5,0,5,1,5,),
    array(2,5,2,1,0,5,1,5,),
    array(2,5,2,5,0,5,1,5,),
    array(2,5,2,5,0,5,1,5,),
    array(0,5,0,5,0,5,1,5,),
    array(0,5,0,5,0,5,1,5,),

    );


    $red=0;
    array_walk_recursive($a, function($v) use(&$red){ if($v==2) {++$red;}});
    echo $red;
    echo '<br>';
    $blue=0;
    array_walk_recursive($a, function($v) use(&$blue){ if($v==1) {++$blue;}});
    echo $blue;




    $w0=-10;
    $w1=50;
    $w2=-30;
    $v=$w0+($w1*$blue)+($w2*$red);
    echo '<br>';
    echo $v;


    $find = new stdClass();
    foreach($a as $i=>$row){
    foreach($row as $j=>$data){
    if($data===1){
    $v=$w0+($w1*$blue)+($w2*$red);
    if(!isset($find->value) || $v > $find->value){
    $find->value = $v;
    $find->i = $i;
    $find->j = $j;
    }
    }
    }
    }

    var_dump($find );
    ?>

    یعنی تو خط 37 شرط && بزاریم بگیم هر خونه ای که سطر بعد و ستون بعدش 0 باشه؟؟؟؟؟؟؟؟

  3. #3

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

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


    // مهره ما در خانه ij قرار دارد.
    $data = $a[$i][$j]
    //یک بار برای خانه جلو سمت راست بررسی کنید.
    $target = $a[$i+1][$j+1];

    $find->value = $v;
    $find->i = $i;
    $find->j = $j;
    find->target_i = $i+1;
    $find->target_j = $j+1;

    //یک بار هم برای خانه جلو سمت چپ بررسی کنید.
    $target = $a[$i+1][$j-1];

    $find->value = $v;
    $find->i = $i;
    $find->j = $j;
    find->target_i = $i+1;
    $find->target_j = $j-1;



    (به آی و جی خودتان دقت کنید من نمیدونم کدام سطر کدام ستون است. در ضمن برای یک بازیکن اگر سطر جلو i+1 باشد برای حریف او سطر جلو باید i-1 در نظر گرفته شود)

    قبلا به دنبال یک مهره بود ولی الان به دنبال یافتن حرکت مناسب هستیم بنابراین بجای $find از نام $move استفاده کنیم با معنی تر است.

  4. #4

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

    نقل قول نوشته شده توسط ali_sed مشاهده تاپیک
    چند نکته هست اول اینکه فقط سطر و ستون بعد کافی نیست. سطر جلویی یه ستون قبل و یه ستون بعد را باید بررسی کنید. چون هر مهره میتونه به صورت اریب به چپ و یا راست حرکت کنه. البته باید حالت های استثنا هم در نظر بگیرید مثلا وقتی که مهره در ستون 0 هست دیگه به سمت چپ نمیتونه بره. بنابراین فقط مهره مهم نیست بلکه شما باید حرکت های مجاز را در نظر بگیرید و برای هر کدام v را محاسبه و بررسی کنید. بنابراین بجای اینکه تنها موقعیت مهره را ذخیره کنید بهتر است موقعیت خانه هدف را نیز همان موقع ذخیره کنید. متاسفانه درس یادگیری ماشین نداشتم وگرنه بیشتر کمکتان می کردم.


    // مهره ما در خانه ij قرار دارد.
    $data = $a[$i][$j]
    //یک بار برای خانه جلو سمت راست بررسی کنید.
    $target = $a[$i+1][$j+1];

    $find->value = $v;
    $find->i = $i;
    $find->j = $j;
    find->target_i = $i+1;
    $find->target_j = $j+1;

    //یک بار هم برای خانه جلو سمت چپ بررسی کنید.
    $target = $a[$i+1][$j-1];

    $find->value = $v;
    $find->i = $i;
    $find->j = $j;
    find->target_i = $i+1;
    $find->target_j = $j-1;



    (به آی و جی خودتان دقت کنید من نمیدونم کدام سطر کدام ستون است. در ضمن برای یک بازیکن اگر سطر جلو i+1 باشد برای حریف او سطر جلو باید i-1 در نظر گرفته شود)

    قبلا به دنبال یک مهره بود ولی الان به دنبال یافتن حرکت مناسب هستیم بنابراین بجای $find از نام $move استفاده کنیم با معنی تر است.
    سلام
    من میخواستم طبق گفته های شما پیش برم ولی نتونستم الان به نظر شما این درسته؟
    طبق نتیجه var_dump اومده اول یکی از یک هارا صفر کرده بعد رفته سراغ یک بعدی
    یعنی همون چیزی که ما میخوایم
    اما من میخوام به ازای هر کدوم بیاد v را حساب کنه (کجا باید بگم بیاد v را حسا کنه که بشه همینی که میخوام)؟؟؟؟؟؟
    اگر v جدید با v قبلی برابر نبود error را حساب کنه و w ها را به روز کند
    اگر هم یکی بود از بینشون random یکی را انتخاب کند
    قسمت random را نمیدونم چجوری بگم از بین اونایی که این شرایط را دارن یکی را انتخاب کن
    بله متوجه هستم که باید سطر بعد و ستون قبل را هم در نظر بگیرم
    گفتم فعلا یک حرکت را بنویسم ببینم اصلا امکانش هست
    ممنون میشم کمکم کنید
    من سعی کردم هر چیزی که تو پست اول گذاشتم را برای یک حرکت به سمت سطر بعد و ستون بعد بنویسم
    ولی قسمت random را نتونستم
    امیدوارم منظورمو متوجه شده باشید
    لطفا اگر با روش خودتون قابل انجام هست برای همین یه حرکت میشه بنویسید
    ممنون میشم
    این آرایه ای که مثال زدم

    $a=array(
    array(1,2,2,1,2),
    array(2,0,2,2,0),
    array(2,2,0,2,2),
    array(2,2,2,2,2),

    );



    این کدی که نوشتم

    foreach($a as $i=>$row){
    foreach($row as $j=>$data){
    if(isset($a[$i+1][$j+1]))
    {
    $db=$a[$i+1][$j+1];
    }
    $r=1;
    if($data===1 && $db===0){
    if(isset($a[$i+1][$j+1]))
    {
    $a[$i+1][$j+1]=1;
    $a[$i][$j]=0;

    }
    $vj=$w0+($w1*$blue)+($w2*$red);
    if($vj != $v)
    {
    $error=$vj-$v;
    $w1=$w1+0.1*$blue*$error;
    $w2=$w2+0.1*$red*$error;
    }
    else
    {
    $r++;
    $rand=rand(1,$r);
    echo $rand;

    }


    //var_dump($a);
    }
    }
    }


    اینم نتیجه خروجی

    array (size=4)
    0 =>
    array (size=5)
    0 => int 0
    1 => int 2
    2 => int 2
    3 => int 1
    4 => int 2
    1 =>
    array (size=5)
    0 => int 2
    1 => int 1
    2 => int 2
    3 => int 2
    4 => int 0
    2 =>
    array (size=5)
    0 => int 2
    1 => int 2
    2 => int 0
    3 => int 2
    4 => int 2
    3 =>
    array (size=5)
    0 => int 2
    1 => int 2
    2 => int 2
    3 => int 2
    4 => int 2
    -360
    C:\wamp64\www\neww\27\page game.php:49:
    array (size=4)
    0 =>
    array (size=5)
    0 => int 0
    1 => int 2
    2 => int 2
    3 => int 0
    4 => int 2
    1 =>
    array (size=5)
    0 => int 2
    1 => int 1
    2 => int 2
    3 => int 2
    4 => int 1
    2 =>
    array (size=5)
    0 => int 2
    1 => int 2
    2 => int 0
    3 => int 2
    4 => int 2
    3 =>
    array (size=5)
    0 => int 2
    1 => int 2
    2 => int 2
    3 => int 2
    4 => int 2

    ولی اگر var_dump را بزارم آخرین کد بیرون از همه آکولادها مستقیم یه آرایه نشان میده که دوتا عدد باهم تغییر کرده
    من گیج شدم نمیدونم
    random کجا باید قرار بگیرد
    گفتم شاید با دستور next() بشه خانه به خانه جلو رفت و اگر حرکتی میتونه انجام بده بیاد فرمول v را حساب کنه اگر هم نه همینجوری بره جلو
    ولی نتونستم دستور next را برای آرایه دو بعدی بنویسم
    به نظر شما next راه خوبی هست؟
    اصلا امکانش هست؟
    آخرین ویرایش به وسیله Salazar.mi : چهارشنبه 08 آبان 1398 در 20:54 عصر

  5. #5

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

    خسته نباشید.

    نیازی به دستور نکست ندارید همین الان دارید داخل دو تا حلقه تو در تو تک تک خانه های بورد را بررسی می کنید. مثلا اگر مهره آبی بود و خانه جلوییش (راست جلو) خالی بود یک حرکت قابل قبول است. حرکت را بصورت موقت انجام داده (برای بررسی حرکت مجاز بعدی نباید تغییری در مهره های بورد اصلی صورت گیرد) و مقدار V را محاسبه می کنیم. من متوجه شیوه محاسبه فرمول v نشدم اینکه مقدار اولیه برای v و w0 و ... چیست.

    اما در هر صورت من فرض می کنم مقدار v اولیه برابر -100 باشه.


    <?php
    $a=array(
    array(2,5,2,5,0,5,1,5,),
    array(2,5,2,5,0,5,1,5,),
    array(2,5,2,5,0,5,1,5,),
    array(2,5,2,1,0,5,1,5,),
    array(2,5,2,5,0,5,1,5,),
    array(2,5,2,5,0,5,1,5,),
    array(0,5,0,5,0,5,1,5,),
    array(0,5,0,5,0,5,1,5,),

    );


    $w0=-10;
    $w1=50;
    $w2=-30;
    $v=$w0+($w1*$blue)+($w2*$red);
    $move = [];

    foreach($a as $i=>$row){
    foreach($row as $j=>$data){
    if(isset($a[$i+1][$j+1]))
    {
    $db=$a[$i+1][$j+1];
    }
    $r=1;
    if($data===1 && $db===0){
    if(isset($a[$i+1][$j+1]))
    {
    //چون نباید بورد اصلی تغییر کند و این حرکت تنها جهت محاسبه وی است بورد را در یک متغییر موقت میریزیم
    $tmp = $a;
    $tmp[$i+1][$j+1]=1;
    $tmp[$i][$j]=0;

    //توجه کنید که در هر حرکت ممکن است تعداد مهره ها تغییر کنید پس باید دوباره شمرده شود
    $red=0;$blue=0;
    array_walk_recursive($tmp, function($val) use(&$red){ if($val==2) {++$red;}elseif($val==1) {++$blue;}});


    $vj=$w0+($w1*$blue)+($w2*$red);
    if($vj > $v)
    {
    $error=$vj-$v;
    $w1=$w1+0.1*$blue*$error;
    $w2=$w2+0.1*$red*$error;
    $v = $vj;
    //ذخیره اطلاعات مربوط به حرکت تا بعدا روی بورد اصلی این حرکت پیاده شود
    $move = [$i, $j, $i+1, $j+1];
    }

    }
    }
    }
    }

    var_dump($v);
    var_dump($move);
    //بهترین حرکت مورد انتخاب شده روی بورد اصلی پیاده شود
    if($move){
    //جای دو خانه را با هم عضو کن
    $tmp = $a[$move[0]][$move[1]];
    $a[$move[0]][$move[1]] = $a[$move[2]][$move[3]];
    $a[$move[2]][$move[3]] = $tmp;
    unset($tmp);
    }

  6. #6

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

    نقل قول نوشته شده توسط ali_sed مشاهده تاپیک
    خسته نباشید.

    نیازی به دستور نکست ندارید همین الان دارید داخل دو تا حلقه تو در تو تک تک خانه های بورد را بررسی می کنید. مثلا اگر مهره آبی بود و خانه جلوییش (راست جلو) خالی بود یک حرکت قابل قبول است. حرکت را بصورت موقت انجام داده (برای بررسی حرکت مجاز بعدی نباید تغییری در مهره های بورد اصلی صورت گیرد) و مقدار V را محاسبه می کنیم. من متوجه شیوه محاسبه فرمول v نشدم اینکه مقدار اولیه برای v و w0 و ... چیست.

    اما در هر صورت من فرض می کنم مقدار v اولیه برابر -100 باشه.


    <?php
    $a=array(
    array(2,5,2,5,0,5,1,5,),
    array(2,5,2,5,0,5,1,5,),
    array(2,5,2,5,0,5,1,5,),
    array(2,5,2,1,0,5,1,5,),
    array(2,5,2,5,0,5,1,5,),
    array(2,5,2,5,0,5,1,5,),
    array(0,5,0,5,0,5,1,5,),
    array(0,5,0,5,0,5,1,5,),

    );


    $w0=-10;
    $w1=50;
    $w2=-30;
    $v=$w0+($w1*$blue)+($w2*$red);
    $move = [];

    foreach($a as $i=>$row){
    foreach($row as $j=>$data){
    if(isset($a[$i+1][$j+1]))
    {
    $db=$a[$i+1][$j+1];
    }
    $r=1;
    if($data===1 && $db===0){
    if(isset($a[$i+1][$j+1]))
    {
    //چون نباید بورد اصلی تغییر کند و این حرکت تنها جهت محاسبه وی است بورد را در یک متغییر موقت میریزیم
    $tmp = $a;
    $tmp[$i+1][$j+1]=1;
    $tmp[$i][$j]=0;

    //توجه کنید که در هر حرکت ممکن است تعداد مهره ها تغییر کنید پس باید دوباره شمرده شود
    $red=0;$blue=0;
    array_walk_recursive($tmp, function($val) use(&$red){ if($val==2) {++$red;}elseif($val==1) {++$blue;}});


    $vj=$w0+($w1*$blue)+($w2*$red);
    if($vj > $v)
    {
    $error=$vj-$v;
    $w1=$w1+0.1*$blue*$error;
    $w2=$w2+0.1*$red*$error;
    $v = $vj;
    //ذخیره اطلاعات مربوط به حرکت تا بعدا روی بورد اصلی این حرکت پیاده شود
    $move = [$i, $j, $i+1, $j+1];
    }

    }
    }
    }
    }

    var_dump($v);
    var_dump($move);
    //بهترین حرکت مورد انتخاب شده روی بورد اصلی پیاده شود
    if($move){
    //جای دو خانه را با هم عضو کن
    $tmp = $a[$move[0]][$move[1]];
    $a[$move[0]][$move[1]] = $a[$move[2]][$move[3]];
    $a[$move[2]][$move[3]] = $tmp;
    unset($tmp);
    }
    سلامت باشید.
    بی نهایت ممنونم که جواب دادین
    راستش من باید چیزی که شما نوشتین چندین بار بخوانم
    فقط در جواب بگم
    متغیر v داره ارزش صفحه را میگه
    و w ها یه سری وزن اند که به هر گروه مهره داده میشه
    هر بار میاد متغیر v را میسنجه اگر همه حرکت ها برابر با حالت قبلی بود از بینشون random یه حرکت را انجام میده
    اگر v با قبلی برابر نبود با v قبلی میسنجه اگر مقدارش بیشتر بود v جدید انتخاب میشه
    بعد مقدار error را حساب میکنه
    با error میاد مقدار w ها را به روز میکند
    این کار را انقدر انجام میده تا بهترین w ها پیدا بشن
    بی نهایت ممنونم که جواب دادین
    خدا خیرتون بده دعا میکنم هرچی میخواین خدا بهتون بده
    شرمندم ولی اگر امکانش براتون بود میشه در مورد قسمت randomاشم یه راهنمایی بفرمایید
    بازم بی نهایت تشکر میکنم
    شرمندم خیلی اذیتتون کردم
    بازم ممنونم
    آخرین ویرایش به وسیله Salazar.mi : چهارشنبه 08 آبان 1398 در 21:58 عصر

  7. #7

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

    البته $a هم باید اصلاح بشه کلا 0 خالی 1 آبی 2 قرمز:

    $a = [
    [0,2,0,2,0,2,0,2],
    [2,0,2,0,2,0,2,0],
    [0,2,0,2,0,2,0,2],
    [0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0],
    [1,0,1,0,1,0,1,0],
    [0,1,0,1,0,1,0,1],
    [1,0,1,0,1,0,1,0],
    ];

  8. #8

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

    خب آخرش نگفتید وقتی هنوز بازی شروع نشده چه مقداری برای v w0 w1 w2 باید در نظر بگیریم و چرا؟ چون v وابسته به مقادیر w0 w1 w2 می باشد.

    تا جایی که من متوجه شدم اول بازیکن آبی شروع می کنه (یک انسان) حالا برنامه (قرمز) قراره بهترین حرکت مناسب را پیدا کنه (برای سادگی تنها یک عمق در نظر گرفته شده است). فرض کنیم بازیکن قرمز 8 حرکت مجاز دارد برای هر حرکت مقدار V را محاسبه می کنیم و بزرگترین آن را پیدا می کنیم اگر چند حرکت V برابر داشتند رندوم یکی را انتخاب کنه. مثلا ممکنه برای دو حرکت مقدار V = 10 باشد و برای 6 حرکت دیگر برابر 5 باشد لذا باید از بین دو حرکت یکی بصورت دندوم انتخاب شود.

    اگر اینطور باشه شما می توانید تمامی حرکات با V برابر را در یک آرایه بریزید و بعد یکی را بصورت رندوم انتخاب کنید. یا اینکه دو به دو یکی را رندوم انتخاب کنید.یعنی اینجوری:

    if($vj > $v || ($vj == $v && rand(0,1)))
    {
    $error=$vj-$v;
    $w1=$w1+0.1*$blue*$error;
    $w2=$w2+0.1*$red*$error;
    $v = $vj;
    //ذخیره اطلاعات مربوط به حرکت تا بعدا روی بورد اصلی این حرکت پیاده شود
    $move = [$i, $j, $i+1, $j+1];
    }


    فرض کنیم اولین حرکت انتخاب شده است برای حرکت مجاز بعدی وی را محاسبه می کنیم و برابر وی قبلی می شود. rand(0,1) - یا صفر است یا یک - اگر یک بود حرکت منتخب را عوض می کند و اگر صفر بود همان حرکت قبلی را نگه می دارد. اگر وی حرکت سوم نیز برابر شد تنها بین حرکت منتخب با این حرکت جدید دوباره یکی را بصورت رندوم انتخاب می کنیم و الی آخر. این حالت پیاده سازیش خیلی راحت تره ولی دقت کنید که میزان شانس انتخاب عناصر با این روش برابر نیست.

    سوالم من اینه:
    الان قرمز (کامپیوتر) حرکت منتخب را انجام میدهد و نوبت بازیکن آبی هست که یک شخص آن را انجام میدهد و دوباره نوبت برنامه می شود درسته؟
    حالا که نوبت برنامه شد آیا از V حرکت قبلی بازیکن قرمز برای یافتن حرکت جدید استفاده می کنیم یا نه؟

  9. #9

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

    نقل قول نوشته شده توسط ali_sed مشاهده تاپیک
    خب آخرش نگفتید وقتی هنوز بازی شروع نشده چه مقداری برای v w0 w1 w2 باید در نظر بگیریم و چرا؟ چون v وابسته به مقادیر w0 w1 w2 می باشد.

    تا جایی که من متوجه شدم اول بازیکن آبی شروع می کنه (یک انسان) حالا برنامه (قرمز) قراره بهترین حرکت مناسب را پیدا کنه (برای سادگی تنها یک عمق در نظر گرفته شده است). فرض کنیم بازیکن قرمز 8 حرکت مجاز دارد برای هر حرکت مقدار V را محاسبه می کنیم و بزرگترین آن را پیدا می کنیم اگر چند حرکت V برابر داشتند رندوم یکی را انتخاب کنه. مثلا ممکنه برای دو حرکت مقدار V = 10 باشد و برای 6 حرکت دیگر برابر 5 باشد لذا باید از بین دو حرکت یکی بصورت دندوم انتخاب شود.

    اگر اینطور باشه شما می توانید تمامی حرکات با V برابر را در یک آرایه بریزید و بعد یکی را بصورت رندوم انتخاب کنید. یا اینکه دو به دو یکی را رندوم انتخاب کنید.یعنی اینجوری:

    if($vj > $v || ($vj == $v && rand(0,1)))
    {
    $error=$vj-$v;
    $w1=$w1+0.1*$blue*$error;
    $w2=$w2+0.1*$red*$error;
    $v = $vj;
    //ذخیره اطلاعات مربوط به حرکت تا بعدا روی بورد اصلی این حرکت پیاده شود
    $move = [$i, $j, $i+1, $j+1];
    }


    فرض کنیم اولین حرکت انتخاب شده است برای حرکت مجاز بعدی وی را محاسبه می کنیم و برابر وی قبلی می شود. rand(0,1) - یا صفر است یا یک - اگر یک بود حرکت منتخب را عوض می کند و اگر صفر بود همان حرکت قبلی را نگه می دارد. اگر وی حرکت سوم نیز برابر شد تنها بین حرکت منتخب با این حرکت جدید دوباره یکی را بصورت رندوم انتخاب می کنیم و الی آخر. این حالت پیاده سازیش خیلی راحت تره ولی دقت کنید که میزان شانس انتخاب عناصر با این روش برابر نیست.

    سوالم من اینه:
    الان قرمز (کامپیوتر) حرکت منتخب را انجام میدهد و نوبت بازیکن آبی هست که یک شخص آن را انجام میدهد و دوباره نوبت برنامه می شود درسته؟
    حالا که نوبت برنامه شد آیا از V حرکت قبلی بازیکن قرمز برای یافتن حرکت جدید استفاده می کنیم یا نه؟
    بی نهایت سپاسگذارم از این همه توجه شما
    حقیقتش باید اول برنامه ای نوشته بشه که هم مهره آبی و هم مهره قرمز هردو را کامپیوتر انجام بده تا یادگیری انجام بشه اصطلاحا میگن train
    به ما گفتن برای قسمت یادگیری بیاین قوانین را برای یک بازی بنویسین
    طبق این قوانین همانطور که خودتون گفتین امکان داره wها تغییر کنند یا که نه تغییر نکنند
    در نهایت آخر هر بازی زمانی هست که
    یا v=100 مثلا بازیکن اول برده
    یا v=-100 بازیکن دوم برده
    یا v=0 مساوی شده
    در نهایت آخر هر بازی ما یه سری w جدید داریم میایم برنامه ای که برای یک بازی نوشتیم را تو یه حلقه while میذاریم تا1000 بار برنامه تکرار بشه و هر بار از wقبلی برای w جدید استفاده میکنیم و بهترین w ها پیدا بشن
    بعد با بهترین w میریم برای قسمت تست
    که یک سمت کامپیوتر و یک سمت خودمون قرار داریم
    حالا که نوبت برنامه شد آیا از V حرکت قبلی بازیکن قرمز برای یافتن حرکت جدید استفاده می کنیم یا نه؟
    در جواب این سوال باید بگم طبق چیزی که من فهمیدم v ارزشی هست که به صفحه داده میشه
    هر دفعه از همون v قبلی استفاده میشه
    اما مهم اینه که اگر بازیکن max باشه مثلا مهره آبی باید از بین v ها max را انتخاب کنه
    و اگر بازیکن min باشه مثلا مهره قرمز باید از بین v ها min را انتخاب کنه
    خب آخرش نگفتید وقتی هنوز بازی شروع نشده چه مقداری برای v w0 w1 w2 باید در نظر بگیریم و چرا؟ چون v وابسته به مقادیر w0 w1 w2 می باشد.
    و در جواب این سوال به ما گفتن بیاین در ابتدا یه مقدار پیش فرضی را به wها بدین
    ولی مثلا اگر مهره آبی max بیاین به w متناظر با مهره آبی عدد بیشتر بدین تا به w2
    فکر کنم همه چیز را درباره بازی به شما گفتم فقط دو نکته را نگفتم
    زدن مهره حریف:هر مهره در صورتی که مهره ای که به صورت اریب در مقابلش قرارا دارد مهره حریف باشه و خانه ای که به صورت اریب بعد از مهره حریف قرار داره خالی باش میتونه از خانه خودش بره در خانه خالی قرار بگیرد با اینکار مهره حریف حذف میشه
    مهره شاه: هر مهره میتونه فقط به صورت اریب به سمت جلو بره ولی اگر مثلا مهره های آبی پایین صفحه هستند بتونن خودشونو به بالاترین سطر صفحه برسونن تبدیل به مهره شاه میشن و میتونن به سمت عقب هم به صورت اریب حرکت کنند
    بی نهایت ممنونم که جواب دادین
    بی نهایت ممنونم
    نمیدونم چجوری جبران کنم
    امیدوارم هرچیزی دوست دارین خدا بهتون بده
    واقعا ممنونممم
    آخرین ویرایش به وسیله Salazar.mi : چهارشنبه 08 آبان 1398 در 23:29 عصر

  10. #10

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

    یه چیزی بپرسم
    الان یعنی این یه جمله که نوشتین

    ($vj== $v&& rand(0,1)


    میاد میگه اگر vها برابر بود rand استفاده کن
    اگر random صفر بود خودشو بزار
    اگر random یک بود تغییر بده
    شرمندم دارم دوباره میپرسم

  11. #11

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

    در پایین همان قسمت توضیح دادم: با توجه به اینکه در هر مرحله یک v ساخته می شود برای اینکه بین چند تا یکی را رندوم انتخاب کنیم تا زمانی که همه ساخته نشده اند نمیتوان رندوم انتخاب کرد پس باید همه را در یک آرایه ذخیره کنید و در پایان یکی را بصورت رندوم انتخاب کنید. اما یک راه دیگر انتخاب دو به دو است فرض کنید 3 تا v یکسان داریم. اول بین v1 , v2 یکی را رندوم انتخاب می کنیم بعد بین v3 و نتیجه قبلی یکی را بصورت رندوم انتخاب می کنیم. (فقط اینکه در روش دوم احتمال 3 اومدن 50 درصد و احتمال 1 اومدن 25 درصد و احتمال 2 اومدن نیز 25 درصد است بنابراین اگر رندوم بودن با احتمال برابر مهم است بهتر است از همان روش اول استفاده کنید (فعلا می توانید از این قسمت گذر کنید و از همین روش ساده که گفتم استفاده کنید.))

  12. #12

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

    نقل قول نوشته شده توسط ali_sed مشاهده تاپیک
    در پایین همان قسمت توضیح دادم: با توجه به اینکه در هر مرحله یک v ساخته می شود برای اینکه بین چند تا یکی را رندوم انتخاب کنیم تا زمانی که همه ساخته نشده اند نمیتوان رندوم انتخاب کرد پس باید همه را در یک آرایه ذخیره کنید و در پایان یکی را بصورت رندوم انتخاب کنید. اما یک راه دیگر انتخاب دو به دو است فرض کنید 3 تا v یکسان داریم. اول بین v1 , v2 یکی را رندوم انتخاب می کنیم بعد بین v3 و نتیجه قبلی یکی را بصورت رندوم انتخاب می کنیم. (فقط اینکه در روش دوم احتمال 3 اومدن 50 درصد و احتمال 1 اومدن 25 درصد و احتمال 2 اومدن نیز 25 درصد است بنابراین اگر رندوم بودن با احتمال برابر مهم است بهتر است از همان روش اول استفاده کنید (فعلا می توانید از این قسمت گذر کنید و از همین روش ساده که گفتم استفاده کنید.))
    بله حق با شماست
    ولی میخواستم دوباره بپرسم تا مطمین بشم ببخشید شرمنده
    بی نهایت ازتون ممنونم کدی که نوشتین را اجرا کردم کاملا درست کار میکنه
    فقط باید به جای عدد 1 عدد 2 بزاریم
    چون اعداد 2(ممهره قرمز) خونه سطر بعد و ستون بعد دارن که مشکل از کد اولی بود که خودم نوشتم
    فقط یه چیزی وقتی دایم f5 میزنم و مقادیر آرایه move به صورت رندوم عوض میشه بین همه حالت ها یه حالتی انتخاب میشه که آرایه move خالی میشه و آرایه a تغییر نمیکند
    در واقع هیچ حرکتی نمیتونه انجام بده
    چطوری میتونیم بگیم حتما یه حرکتی انجام بده
    ممنون میشم جواب بدین
    خودم اینو امتحان کردم ولی باز هم احتمال داره آرایه move خالی باشه

    $move = [$i, $j, $i+1, $j+1];
    if(empty($move))
    {
    $move = [$i, $j, $i+1, $j+1];
    }

    آخرین ویرایش به وسیله Salazar.mi : پنج شنبه 09 آبان 1398 در 11:45 صبح

  13. #13

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

    برای دیباگ بهتره داخل حلقه به ازای هر خانه از بورد اطلاعات مهم را در یک خط نمایش دهید و بررسی کنید مشکل از کجاست.
    ممکنه به این علت باشه که هیچ vj ای بزرگتر از v پیدا نکرده باشه که به نحوه محاسبه vj برمیگردد. در هر صورت دیباگ کنید.

  14. #14

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

    یه سوال دیگه شرمنده
    ولی آیا امکان داره در php بگیم همه اعداد را به صورت float در نظر بگیر
    یا باید برای هر کدوم جدا بگیم

    $w0=-10;
    $fw0=floatval($w0);
    $w1=50;
    $fw1=floatval($w1);
    $w2=-30;
    $fw2=floatval($w2);
    $v=$fw0+($fw1*$blue)+($fw2*$red);
    $fv=floatval($v);

  15. #15

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

    نقل قول نوشته شده توسط ali_sed مشاهده تاپیک
    برای دیباگ بهتره داخل حلقه به ازای هر خانه از بورد اطلاعات مهم را در یک خط نمایش دهید و بررسی کنید مشکل از کجاست.
    ممکنه به این علت باشه که هیچ vj ای بزرگتر از v پیدا نکرده باشه که به نحوه محاسبه vj برمیگردد. در هر صورت دیباگ کنید.
    میخواستم این پست را پاک کنم نشد مشکلمو پایین نوشتم
    آخرین ویرایش به وسیله Salazar.mi : جمعه 10 آبان 1398 در 17:07 عصر

  16. #16

    نقل قول: بازی چکرز با الگوریتم minimax با یک عمق برای یادگیری

    اینجا میخوام بگم
    بیا تو حالت اول بین همه اون هایی که این شرایط را دارن

    $data===2 && $db===1 && $dbb===0

    کوچکترین را انتخاب کن بزار $vj1
    بعد متغیر های w را طبق مقدار vj1 به روز کن که برای اینکار نیاز داریم که vj1 را از v اولیه کم کنیم ولی متغیر v را تغییر نباید تغییر بدیم
    بعدش بین اونایی که این شرایط را دارند

    $data===2 && $db===0

    کوچکترین را انتخاب کن بزار $vj2
    بعد متغیر های w را طبق مقدار vj2 به روز کن که برای اینکار نیاز داریم که vj2 را از v اولیه کم کنیم ولی متغیر v را تغییر نباید تغییر بدیم
    بعد بین این $vj1 و $vj2 هر کدام کوچکتر بود حرکت مربوط به اونو انجام بده
    از متغیر global هم استفاده کردم ولی نشد
    $vj1 را با $vj2 برابر میدونه در واقع نیست $vj1 باید کمتر باشه
    تو آرایه a هم هیچ تغییری ایجاد نمیکند

    چرا نمیدونم؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟؟ ؟؟؟؟؟؟





    <?php
    $a = [
    [0,2,0,2,0,2,0,2],
    [2,0,2,0,2,0,2,0],
    [0,2,0,2,0,2,0,2],
    [0,0,1,0,0,0,0,0],
    [0,0,0,0,0,0,0,0],
    [1,0,1,0,1,0,1,0],
    [0,1,0,1,0,1,0,1],
    [1,0,1,0,1,0,1,0],
    ];

    $red = $blue = 0;
    array_walk_recursive($a, function($t) use(&$red, &$blue)
    {
    if($t==1) {++$blue;}
    elseif($t==2) {++$red;}
    });
    global $w0j1;
    global $w1j1;
    global $w2j1;
    global $w0j2;
    global $w1j2;
    global $w2j2;
    global $vj1;
    global $vj2;
    global $w0;
    global $w1;
    global $w2;
    $w0=-10;
    $w1=50;
    $w2=-30;
    global $v;
    $v=$w0+($w1*$blue)+($w2*$red);
    global $vj1;
    global $vj2;
    $move = [];
    $move1 = [];
    $move2 = [];

    foreach($a as $i=>$row){
    foreach($row as $j=>$data){
    if(isset($a[$i+1][$j+1]))
    {
    $db=$a[$i+1][$j+1];
    }
    if(isset($a[$i+2][$j+2]))
    {
    $dbb=$a[$i+2][$j+2];
    }
    if($data===2 && $db===1 && $dbb===0){
    if(isset($a[$i+2][$j+2]))
    {
    //چون نباید بورد اصلی تغییر کند و این حرکت تنها جهت محاسبه وی است بورد را در یک متغییر موقت میریزیم
    $tmp1 = $a;
    $tmp1[$i+2][$j+2]=2;
    $tmp1[$i+1][$j+1]=0;
    $tmp1[$i][$j]=0;


    //توجه کنید که در هر حرکت ممکن است تعداد مهره ها تغییر کنید پس باید دوباره شمرده شود
    $red = $blue = 0;
    array_walk_recursive($tmp1, function($t) use(&$red, &$blue)
    {
    if($t==1) {++$blue;}
    elseif($t==2) {++$red;}

    });

    $vj1=$w0+($w1*$blue)+($w2*$red);
    if($vj1 < $v || ($vj1 == $v && rand(0,1)))
    {
    $error=$vj1-$v;
    $w0j1=$w0+0.1*1*$error;
    $w1j1=$w1+0.1*$blue*$error;
    $w2j1=$w2+0.1*$red*$error;
    //ذخیره اطلاعات مربوط به حرکت تا بعدا روی بورد اصلی این حرکت پیاده شود
    $move1 = [$i, $j, $i+1, $j+1,$i+2,$j+2];

    }

    }


    }



    if($data===2 && $db===0){
    if(isset($a[$i+1][$j+1]))
    {
    //چون نباید بورد اصلی تغییر کند و این حرکت تنها جهت محاسبه وی است بورد را در یک متغییر موقت میریزیم
    $tmp2 = $a;
    $tmp2[$i+1][$j+1]=2;
    $tmp2[$i][$j]=0;


    //توجه کنید که در هر حرکت ممکن است تعداد مهره ها تغییر کنید پس باید دوباره شمرده شود
    $red = $blue = 0;
    array_walk_recursive($tmp2, function($t) use(&$red, &$blue)
    {
    if($t==1) {++$blue;}
    elseif($t==2) {++$red;}
    });

    $vj2=$w0+($w1*$blue)+($w2*$red);
    if($vj2 < $v || ($vj2 == $v && rand(0,1)))
    {
    $error=$vj2-$v;
    $w0j2=$w0+0.1*1*$error;
    $w1j2=$w1+0.1*$blue*$error;
    $w2j2=$w2+0.1*$red*$error;
    //ذخیره اطلاعات مربوط به حرکت تا بعدا روی بورد اصلی این حرکت پیاده شود
    $move2 = [$i, $j, $i+1, $j+1];
    }

    }

    }

    //انتخاب j1
    if($vj1<$vj2 || $vj2===null)
    {
    if($move1)
    {
    $v=$w0j1+($w1j1*$blue)+($w2j1*$red);
    // جای دو خانه را با هم عضو کن خانه وسط را صفر کن
    $tmp1 = $a[$move1[0]][$move1[1]];
    $a[$move1[0]][$move1[1]] = $a[$move1[4]][$move1[5]];
    $a[$move1[2]][$move1[3]] = 0;
    $a[$move1[4]][$move1[5]] = $tmp1;


    unset($tmp1);
    }
    }

    //انتخاب j2
    elseif($vj2<$vj1 || $vj1===null)
    {
    if($move2)
    {
    $v=$w0j2+($w1j2*$blue)+($w2j2*$red);
    //جای دو خانه را با هم عضو کن
    $tmp2 = $a[$move2[0]][$move2[1]];
    $a[$move2[0]][$move2[1]] = $a[$move2[2]][$move2[3]];
    $a[$move2[2]][$move2[3]] = $tmp2;


    unset($tmp2);

    }
    }



    }

    }

    var_dump($v);
    var_dump($vj1);
    var_dump($vj2);
    var_dump($move2);
    var_dump($move1);


    var_dump($a);


    ?>






    ممنون میشم کمکم کنید
    آخرین ویرایش به وسیله Salazar.mi : جمعه 10 آبان 1398 در 20:23 عصر

تاپیک های مشابه

  1. الگوریتم minimax برای بازی دوز
    نوشته شده توسط zt1990 در بخش الگوریتم، کامپایلر، هوش مصنوعی و ساختمان داده ها
    پاسخ: 1
    آخرین پست: یک شنبه 08 تیر 1393, 21:58 عصر
  2. سوال: طریقه پیاده سازی الگوریتم minimax با C++‎
    نوشته شده توسط Rezvane.R در بخش برنامه نویسی با زبان C و ++C
    پاسخ: 0
    آخرین پست: یک شنبه 08 بهمن 1391, 11:57 صبح
  3. سوال: پیاده سازی بازی Reversi با الگوریتم Minimax
    نوشته شده توسط -Azure- در بخش الگوریتم، کامپایلر، هوش مصنوعی و ساختمان داده ها
    پاسخ: 0
    آخرین پست: شنبه 08 اسفند 1388, 16:05 عصر
  4. روش ایجاد یک درخت مینی ماکس MiniMax
    نوشته شده توسط hbi در بخش الگوریتم، کامپایلر، هوش مصنوعی و ساختمان داده ها
    پاسخ: 1
    آخرین پست: پنج شنبه 18 بهمن 1386, 00:45 صبح

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •