شما اینجا هستید

۱-۲ کلاس گردشگر تصادفی

پیغام خطا

Deprecated function: The each() function is deprecated. This message will be suppressed on further calls در book_prev() (خط 775 در /home/molavy/public_html/modules/book/book.module).

اجازه بدهید با ساخت کلاس Walker مقداری از برنامه نویسی شی گرا بگوییم. فقط یک نگاه سرسری به آن می اندازیم.اگر شما تا کنون با شی گرایی کار نکرده اید، ممکن است نیاز باشد بیشتر در مورد آن بدانید. فکر کنم اگر همین جا دست نگه دارید و قبل از ادامه نگاهی بهمفاهیم پایه در سایت processing بیندازید.

یک شی در processing یک مدخل است که حاوی داده ها و توابع است. ما نگاهی به طراحی شی Walker می اندازیم. این تابع خودش داده های مکان حرکتش ( جایی که در صفحه قرار گرفته است) و قابلیت حرکت های اساسی مانند نمایش خودش روی صفحه و قدم برداشتن) را دارد.

یک کلاس یک قالب برای ساخت یک نمونه واقعی از اشیاء است. کلاس را مانند یک قالب کیک در نظر بگیرید. اشیاء هم کیک هستند.

اجازه بدهید با تعریف تابع Walker شروع کنیم-- جایی که شی گردشگر معنی می دهد. گردشگر ما فقط نیاز به دو مدل داده دارد-- یک شماره برای موقعیت x و یکی برای موقعیت y.

 class Walker {
  //[full] Objects have data.
  int x;
  int y;
  //[end]

هر کلاس باید سازنده ای داشته باشد. سازنده یک تابع خاص است که وقتی شی برای اولین بار ساخته می شود فراخوانی می شود. شما می توانید آن را مانند تابع setup() تصور کنید. در سازنده ما موقعیت اولیه گردشگر را در صفحه مقدار دهی اولیه می کنیم( در اینجا وصط پنجره).

//[full] Objects have a constructor where they are initialized.
  Walker() {
    x = width/2;
    y = height/2;
  }
  //[end]

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

 //[full] Objects have functions.
  void display() {
    stroke(0);
    point(x,y);
  }
  //[end]

تابع دوم کمک می کند گردشگر یک قدم بردارد. حالا، اینجا جایی است که چیز ها یک مقدار جالب تر می شوند. وقتی را که آمدیم روی زمین و خواستیم قدم های تصادفی برداریم را به خاطر می آورید؟ خوب، حالا ما می توانیم از یک پنجره در processing استفاده می کنیم برای شبیه سازی سطح زمین. چهار حالت برای قدم برداشتن وجود دارد.یک قدم راست می تواند با افزایش مقدار x++)x) و یک قدم به چپ می تواند به کاهش x--)x) شبیه سازی شود. همچنین یک قدم به جلو با رفتن به یک پیکسل پایین و افزایش y++)y) و یک قدم به عقب با رفتن به یک پیکسل بالا --y شبیه سازی می شودچگونه یکی از این وضعیت ها را انتخاب کنیم؟ پیشتر ما گفتیم که می توانیم دو تا سکه بیندازیمدر processing وقتی ما می خواهیم به صورت تصادفی از لیست از اختیارات انتخاب کنیم، ما می توانیم یک عدد تصادفی با استفاده از تابع random بگیریم.

 

  void step() {
    // 0, 1, 2, or 3
    int choice = int(random(4));

خط بالا یک عدد ممیز شناور بین صفر تا چهار بر می گرداند و آن را به مقدار صحیح تبدیل می کندنتیجه عددی بین 0 ,1 ,2 ,3 استاگر بخواهیم به صورت فنی بگویم بالاترین عدد هیچ وقت چهار نیست، اما به صورت خلاصه اگر تابع تصادفی عدد ۳.۹۹۹۹۹۹( با هر تعداد ۹ که بتواند داشته باشد) برگرداند، هنگام تبدیل به مقدار صحیح(int) قسمت صحیح را بر میگرداندبعد از آن ما با وابسته به عدد تصادفی برگردانده شده یک قدم بر می داریم( چپ، راست، بالا یا پایین).

 

  //[full] The random “choice” determines our step.
    if (choice == 0) {
      x++;
    } else if (choice == 1) {
      x--;
    } else if (choice == 2) {
      y++;
    } else {
      y--;
    }
    //[end]
  }
}

حال که ما کلاسمان را نوشتیم، زمان آن است که یک شی گردشگر واقعی در قسمت اصلی sketch یعنی setup و draw ایجاد کنیمدر نظر بگیرید ما دنبال مدل کردن برداشتن یک قدم تصادفی هستیم، ما یک مقدار متغییر عمومی از نوع Walker بر میداریم.

 

Walker w;

بعد از آن ما با فراخوانی سازنده با استفاده از عملگر new یک شی در setup می سازیم

 

 void setup() {
  size(640,360);
  // Create the Walker.
  w = new Walker();  //[bold]
  background(255);
}

در انتها در هر حلقه در draw، ما از Walker می خواهیم که یک قدم بردارد و یک نقطه در آنجا ترسیم کنید.

 

 void draw() {
  //[full] Call functions on the Walker.
  w.step(); //[bold]
  w.display(); //[bold]
  //[end]
}

به دلیل اینکه ما پس زمینه را تنها یک بار در setup رسم کردیم، به جای هردفعه پاک کردن آن در هر ترسیم در draw، ما ما یک قدم زدن تصادفی رو در به صورت دنباله دار در پنجره processing می بینیم

Your browser does not support the canvas tag.

 

 

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

برای اینکه بتوانیم کاری کنیم که شی گردشگر بتواند روی هر پیکسلی که در اطرافش هست قدم بگذارد(یا در جای خودش ثابت بماند)، ما می توانیم یک عدد از صفر تا ۸ برداریم(نه انتخاب). اگرچه، یک راه بهینه تر برای نوشتن کد این است که در هر قدم سه حالت ممکن برای محور x یعنی (۱- ، صفر یا ۱) و سه حالت برای محور y داشته باشیم.

 

   void step() {
    //[full] Yields -1, 0, or 1
    int stepx = int(random(3))-1;
    int stepy = int(random(3))-1;
    //[end]
    x += stepx;
    y += stepy;
  }

کمی جلو تر برویم، می توانیم از مقدار ممیز شناور (مثالا اعداد اعشاری) برای x یا y به جای آن استفاده کنیم و حرکت ما طبق یک حرکت دل بخواهی بین ۱- و ۱ باشد.

 

 void step() {
    //[full] Yields any floating point number between -1.0 and 1.0
    float stepx = random(-1, 1);
    float stepy = random(-1, 1);
    //[end]
    x += stepx;
    y += stepy;
  }

تمام این تغییرات روی قدم برداشتن تصادفی قدیمی یک چیز یکسان دارند: در هر لحظه از زمان، احتمال این که گردشگر یک قدم در هر مسیر بردارد برابر است با یک تقسیم بر تعداد حالاتی که می تواند در یک قدم برداردبه عبارت دیگر، اگر چهار حالت ممکن برای قدم برداشتن داشته باشیم، احتمال قدم برداشتن در هر مسیر ۱/۴ است (یا ۲۵٪) استبا هشت حالت احتمال قدم برداشتن در هر مسیر ۱ تقسیم بر ۹ است (یا ۱۱.۱٪) .

این حالتی است که تابع random کار می کندفرایند تولید مقدار تصادفی( که در این مجال توضیح آن نمی گنجد) یک توزیع یکنواخت از اعداد را فراهم می کند.ما می توانیم با تست این توزیع با یک نمایش در یک sketch در processing و شمردن اینکه هر دفعه چه مقداری فراهم می شود و نمایش آن روی گراف با تغییر ارتفاع یک مستطیل نشان دهیم.

 

 

 

 

// An array to keep track of how often random numbers are picked
int[] randomCounts;

void setup() {
  size(640,240);
  randomCounts = new int[20];
}

void draw() {
  background(255);

  // Pick a random number and increase the count.
  int index = int(random(randomCounts.length));
  randomCounts[index]++;

  stroke(0);
  fill(175);
  int w = width/randomCounts.length;
  //[full] Graphing the results
  for (int x = 0; x < randomCounts.length; x++) {
    rect(x*w,height-randomCounts[x],w-1,randomCounts[x]);
  }
  //[end]
}

Your browser does not support the canvas tag.

 

 

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

اعداد تصادفی کاذب

اعداد تصادفی ساخته شده توسط تابع random در حقیقت تصادفی نیستندبه همین دلیل آنها را تصادفی کاذب یا Pseudo-Random می نامنداینها نتایج توابع ریاضی شبیه سازی تصادفی بودن هستنداین تابع در گذر زمان از یک الگو تبعیت می کند، اما این زمان برای ما بسیار طولانی استبه همین دلیل می توان آن را تصادفی بودن واقعی در نظر گرفت.

 

 

 

 

 

تمرین ۱-۱ یک گردشگر تصادفی بنویسید که تمایل به حرکت تنها به پایین و راست داشته باشد.(در قسمت بعد راه حل را می بینیم. )

دیدگاه جدیدی بگذارید