public int

‫בתרגול הקודם‬
‫• הורשה‪:‬‬
‫–‬
‫–‬
‫–‬
‫–‬
‫–‬
‫–‬
‫ניתן להרחיב רק מחלקה אחת‬
‫כל מה שלא ‪ – private‬עובר בהורשה‬
‫המילה השמורה ‪super‬‬
‫יצירת היררכיה‬
‫‪ Object‬היא שורש ההיררכיה‬
‫דריסה‬
‫• אופרטור ‪instanceof‬‬
‫• המחלקה ‪Object‬‬
‫– השיטות ‪equals ,toString‬‬
‫• פולימורפיזם‬
‫‪1‬‬
‫– חד כיווניות‬
‫תרגול ‪11‬‬
‫המשך תכנות מונחה עצמים‬
‫‪2‬‬
‫היום בתרגול‬
‫• כללי הרשאות בהורשה‬
‫• מחלקות אבסטרקטיות‬
‫‪3‬‬
‫כללי הרשאות (‪ )visibility modifiers‬בהורשה‬
‫‪ – public‬שדות ושיטות המוגדרים כ‪ public-‬ניתנים לגישה מתוך‬
‫ומחוץ למחלקה‪.‬‬
‫‪ – protected‬שדות ושיטות המוגדרים כ‪ protected-‬ניתנים לגישה‬
‫מתוך המחלקה וממחלקות היורשות מהמחלקה‪ ,‬אך אינם ניתן לגישה‬
‫ממחלקות אחרות *‪.‬‬
‫(* ממחלקות אחרות הנמצאות ב ‪ package‬אחר‪ protected .‬מתנהג כמו ‪ public‬באותו‬
‫‪)package‬‬
‫‪ – private‬שדות ושיטות המוגדרים כ‪ private-‬אינם ניתנים לגישה‬
‫מחוץ למחלקה‪ .‬ניסיון לגשת לשדה או שיטה כזו מחוץ למחלקה יעורר‬
‫שגיאת קומפילציה‪.‬‬
‫‪4‬‬
‫) בהורשה‬visibility modifiers( ‫כללי הרשאות‬
‫ זו שגיאת‬,‫שיטות לא יכולות להידרס ע"י שיטה מרמת שיתוף נמוכה יותר‬
:‫ כלומר‬.‫קומפילציה‬
private ‫ או‬protected ‫ עם‬public ‫– לא ניתן לדרוס שיטה‬
private ‫ עם שיטה‬protected ‫– לא ניתן לדרוס שיטה‬
public class Book {
public String getName() {
…
}
}
•
public class Dictionary extends Book {
protected String getName() {
…
}
}
Compilation Error
Book b = new Dictionary();
System.out.println (b.getName() );
?‫ מה ההיגיון מאחורי שגיאה זו‬:‫שאלה‬
‫בלעדיה הייתה מתקבלת סתירה לעקרון‬
‫הפולימורפיזם‬
5
‫כללי הרשאות (‪ )visibility modifiers‬בהורשה‬
‫•‬
‫•‬
‫‪6‬‬
‫משתנים אינם עוברים דריסה בהורשה‪.‬‬
‫שיטות שאינן ‪ private‬עוברות בהורשה‪.‬‬
‫– שיטות פרטיות נועדו למימוש פנימי של מחלקת האב‪ ,‬ואינן ניתנות לשימוש ע"י‬
‫תת מחלקה‪.‬‬
‫– תת‪-‬המחלקה לא מכירה את המשתנים והשיטות הפרטיים של המחלקת האב‪,‬‬
‫ממנה היא יורשת‪ ,‬ולכן עשויה גם להכריז על משתנים ושיטות פרטיים בעלי‬
‫אותו שם וחתימה‪.‬‬
‫סיכום חוקי גישה לשיטות ושדות בהורשה ב‪:Java-‬‬
‫‪ .1‬טיפוס המשתנה (טיפוס המצביע‪ )reference type /‬קובע בזמן הידור אילו שיטות‬
‫ניתן להפעיל על המשתנה ולאילו שדות של המשתנה ניתן לגשת‪.‬‬
‫‪.2‬‬
‫‪.3‬‬
‫‪.4‬‬
‫‪.5‬‬
‫‪7‬‬
‫בקריאה לשיטה שאינה פרטית המופיעה במחלקת‪-‬אב ובתת‪-‬מחלקה‪ ,‬אם ע"י‬
‫קריאה ישירה או ע"י שימוש באופרטור השייכות (‪ ,).‬הקוד המופעל נקבע בהתאם‬
‫למחלקת האובייקט בפועל )‪ )instance type‬שעליו מופעלת השיטה (ומשם‬
‫בסריקה מלמטה למעלה לפי היררכית ההורשה) ‪ -‬שיטת הבצל‪.‬‬
‫שיטה פרטית נגישה רק בתוך ה‪ scope-‬של המחלקה בה היא מוגדרת‪ .‬בקריאה‬
‫לשיטה פרטית‪ ,‬הקוד המופעל נקבע לפי ה‪ scope-‬בו ממוקמת הקריאה‪.‬‬
‫למה זה הגיוני?‬
‫אופרטורלהפעיל‬
‫אם מנסים‬
‫גישהאחרת‪,‬‬
‫ממחלקה‬
‫או לקרוא‬
‫ניתן‬
‫פרטית לא‬
‫השייכות)‪,‬‬
‫לכןללא‬
‫ישירה (‬
‫השמה)‪ ,‬ע"י‬
‫קריאה‬
‫לשיטהלשדה (‬
‫בגישה‬
‫אותה‪.‬‬
‫לחפש‬
‫שבובואפשר‬
‫מקום‪ -‬אחד‬
‫פרטית‪ ,‬יש‬
‫שיטה‬
‫ומשם בסריקה‬
‫הגישה (‬
‫ממוקמת‬
‫‪scope‬‬
‫רקלפי ה‬
‫נקבעת‬
‫הגישה לשדה‬
‫מלמטה למעלה לפי היררכית ההורשה)‪.‬‬
‫בגישה לשדה (קריאה או השמה) שאינו פרטי‪ ,‬ע"י אופרטור השייכות‪ ,‬הגישה‬
‫נקבעת בהתאם למחלקת טיפוס המשתנה )‪ )reference type‬שעליה שייך‬
‫השדה (ומשם בסריקה מלמטה למעלה לפי היררכית ההורשה)‪.‬‬
‫דוגמא‬
‫•‬
‫דוגמה‪:‬‬
‫חנות היא סוג של עסק‬
‫–‬
‫•‬
‫•‬
‫–‬
‫–‬
‫‪8‬‬
‫עסק‪ :‬דמי שכירות‪ ,‬עובדים‪ ,‬הוצאות חודשיות‬
‫חנות‪ :‬פריטי סחורה‪ ,‬הוצאות חודשיות הכוללות אחזקת מלאי‪.‬‬
‫כל מחלקה מומשה ע"י מתכנתת אחרת‬
‫בכל מחלקה מימוש שונה לשיטה פרטית ‪calcSum() -‬‬
‫מבוא למדמ"ח‪ ,‬אונ' בן‪-‬גוריון‪ ,‬תש"ע‬
public class Business {
protected Employee[] employees;
protected double monthlyRent;
......
// calculates total monthly expenses
public double monthlyExpenses() {
double salaries = calcSum();  ‫קריאה לשיטה פרטית‬
return this.monthlyRent + salaries;
}
// calculates monthly salaries
private double calcSum() {
double sum = 0;
for (int i=0; i<this.employees.length; i=i+1) {
sum = sum + this.employees[i].getSalary();
}
return sum;
}
......
}
9
public class Shop extends Business {
protected Item[] items;
......
// override: calculates total monthly expenses
public double monthlyExpenses() {
double itemPrices = calcSum();  ‫קריאה לשיטה פרטית‬
return itemPrices + super.monthlyExpenses();
}
// No override: calculates total item prices
private double calcSum() {
double sum=0;
for (int i=0; i<this.items.length; i=i+1) {
sum = sum + this.items[i].getPrice();
}
return sum;
}
......
}
10
?‫איך תרוץ התוכנית הבאה‬
,‫ בקריאה לשיטה פרטית‬.‫ של המחלקה בה היא מוגדרת‬scope-‫שיטה פרטית נגישה רק בתוך ה‬
.‫ בו ממוקמת הקריאה‬scope-‫הקוד המופעל נקבע לפי ה‬
Business s = new Shop();
s.monthlyExpenses()
Shop extends Business {
public double monthlyExpenses()
{
double itemPrices =
calcSum();
return itemPrices +
super.monthlyExpenses();
}
private double calcSum() {…}
}
Business {
public double monthlyExpenses()
{
double salaries =
calcSum();
return this.monthlyRent
+ salaries;
}
private double calcSum() {…}
}
?monthlyExpenses ‫ מה תחשב‬,protected -‫ ל‬calcSum ‫ אם נשנה את המאפיין של‬:‫שאלה‬
‫ אם ע"י קריאה ישירה או ע"י‬,‫מחלקה‬-‫אב ובתת‬-‫בקריאה לשיטה שאינה פרטית המופיעה במחלקת‬
instance ‫ הקוד המופעל נקבע בהתאם למחלקת האובייקט בפועל‬,).( ‫שימוש באופרטור השייכות‬
‫ שיטת‬- )‫) שעליו מופעלת השיטה (ומשם בסריקה מלמטה למעלה לפי היררכית ההורשה‬type)
.‫הבצל‬
Business s = new Shop();
s.monthlyExpenses()
Shop extends Business {
public double monthlyExpenses()
{
double itemPrices =
calcSum();
return itemPrices +
super.monthlyExpenses();
}
protected double calcSum() {…}
}
Business {
public double monthlyExpenses()
{
double salaries =
calcSum();
return this.monthlyRent
+ salaries;
}
protected double calcSum() {…}
}
‫שאלה‪ :‬ומה במקרה הזה?‬
‫בקריאה לשיטה שאינה פרטית המופיעה במחלקת‪-‬אב ובתת‪-‬מחלקה‪ ,‬אם ע"י קריאה ישירה או ע"י‬
‫שימוש באופרטור השייכות (‪ ,).‬הקוד המופעל נקבע בהתאם למחלקת האובייקט בפועל ‪instance‬‬
‫)‪ )type‬שעליו מופעלת השיטה (ומשם בסריקה מלמטה למעלה לפי היררכית ההורשה) ‪ -‬שיטת‬
‫הבצל‪.‬‬
‫;)(‪Shop s = new Shop‬‬
‫)(‪s.monthlyExpenses‬‬
‫אותו דבר‪...‬‬
‫דוגמה להורשה‬
‫(שאלה ממבחן)‬
‫‪14‬‬
a
public class A {
public class B extends A {
b
private int x;
private int x;
X=1
public int y;
public int y;
X=22
Y=2
public A(int x) {
public B(int xA, int xB) {
Y=24
this.x = x;
super(xA);
this.y = 2*x;
this.x = xB;
X=2
}
this.y = xA + xB;
Y=4
public int getX() { return x; }
}
public int doubleX() { return 2 * getX(); }
public int getX() { return x; }
public int tripleX() { return 3 * x; }
public int superX() {
private int subXhelper() { return x - 1; }
return super.getX();
public int subX() {
}
return subXhelper();
public int tenTimesX() { return 10*x; }
}
private int subXhelper() { return x-2; }
}
}
A a = new A (1);
A b = new B (2, 22);
System.out.println(a.getX());
System.out.println(b.getX());
System.out.println(b.superX());
Output / Notes
1
22
Compilation Error !! (The method superX()
is undefined for the type A)
if (b instanceof B)
System.out.println(b.superX()); Compilation Error !!
15
a
public class A {
public class B extends A {
b
private int x;
private int x;
X=1
public int y;
public int y;
X=22
Y=2
public A(int x) {
public B(int xA, int xB) {
Y=24
this.x = x;
super(xA);
this.y = 2*x;
this.x = xB;
X=2
}
this.y = xA + xB;
Y=4
public int getX() { return x; }
}
public int doubleX() { return 2 * getX(); }
public int getX() { return x; }
public int tripleX() { return 3 * x; }
public int superX() {
private int subXhelper() { return x - 1; }
return super.getX();
public int subX() {
}
return subXhelper();
public int tenTimesX() { return 10*x; }
}
private int subXhelper() { return x-2; }
}
}
A a = new A (1);
A b = new B (2, 22);
Output / Notes
B bb = (B)b;
System.out.println(bb.superX());
2
System.out.println(((B)b).superX());
System.out.println(a.tripleX());
System.out.println(b.tripleX());
2
3
6
16
a
public class A {
public class B extends A {
b
private int x;
private int x;
X=1
public int y;
public int y;
X=22
Y=2
public A(int x) {
public B(int xA, int xB) {
Y=24
this.x = x;
super(xA);
this.y = 2*x;
this.x = xB;
X=2
}
this.y = xA + xB;
Y=4
public int getX() { return x; }
}
public int doubleX() { return 2 * getX(); }
public int getX() { return x; }
public int tripleX() { return 3 * x; }
public int superX() {
private int subXhelper() { return x - 1; }
return super.getX();
public int subX() {
}
return subXhelper();
public int tenTimesX() { return 10*x; }
}
private int subXhelper() { return x-2; }
}
}
A a = new A (1);
A b = new B (2, 22);
Output / Notes
System.out.println(((B)a).tenTimesX()); Run-time Error:
ClassCastException: A cannot be cast to B
System.out.println(((B)b).tenTimesX()); 220
System.out.println(b.doubleX());
44
17
System.out.println(b.subX());
1
a
public class A {
public class B extends A {
b
private int x;
private int x;
X=1
public int y;
public int y;
X=22
Y=2
public A(int x) {
public B(int xA, int xB) {
Y=24
this.x = x;
super(xA);
this.y = 2*x;
this.x = xB;
X=2
}
this.y = xA + xB;
Y=4
public int getX() { return x; }
}
public int doubleX() { return 2 * getX(); }
public int getX() { return x; }
public int tripleX() { return 3 * x; }
public int superX() {
private int subXhelper() { return x - 1; }
return super.getX();
public int subX() {
}
return subXhelper();
public int tenTimesX() { return 10*x; }
}
private int subXhelper() { return x-2; }
}
}
A a = new A (1);
A b = new B (2, 22);
System.out.println(a.y);
System.out.println(b.y);
System.out.println(((B)b).y);
B bb= (B)b;
System.out.println(bb.y);
System.out.println(((A)bb).y);
Output / Notes
‫ ע"י גישה‬,)‫בגישה לשדה (קריאה או השמה‬
2
4 ‫ הגישה לשדה‬,)‫ישירה (ללא אופרטור השייכות‬
‫ בו ממוקמת הגישה‬scope -‫נקבעת לפי ה‬
24
‫(ומשם בסריקה מלמטה למעלה לפי היררכית‬
.)‫ההורשה‬
24
18
4
‫מחלקות אבסטרקטיות‬
‫• כאשר רוצים לחלוק קוד משותף בין מספר מחלקות למרות שאין‬
‫רצון לאפשר יצירת אובייקטים ממחלקת האב‪.‬‬
‫• מחלקת האב‪:‬‬
‫– מכילה קוד משותף‪.‬‬
‫– קובעת אילו שיטות אבסטרקטית על תתי המחלקות לממש‪.‬‬
‫• תת‪-‬מחלקה קונקרטית מממשת שיטות אבסטרקטיות‪.‬‬
‫‪19‬‬
‫מחלקות אבסטרקטיות‬
‫{ >‪public abstract class <name‬‬
‫;) ‪public abstract void <method name> ( ...‬‬
‫…‬
‫}‬
‫• במחלקה אבסטרקטית יכולות להיות שיטות רגילות‪ ,‬כמו בכל‬
‫מחלקה‪.‬‬
‫• בנוסף יכולות להיות לה שיטות אבסטרקטיות‪ :‬שיטות שההגדרה‬
‫שלהן קיימת אבל אין להן מימוש‪.‬‬
‫• אנו מכריזים על מחלקה או על שיטה כאבסטרקטית בעזרת המילה‬
‫השמורה ‪.abstract‬‬
‫‪20‬‬
‫מחלקות אבסטרקטיות‬
‫• מחלקה אבסטרקטית ‪ -‬לא ניתן ליצור ממנה מופעים‪.‬‬
‫{ ‪public abstract class Game‬‬
‫} … { )(‪public Game‬‬
‫…‬
‫}‬
‫!‪// Compilation error‬‬
‫;)(‪Game g = new Game‬‬
‫• מחלקה שמרחיבה מחלקה אבסטרקטית ולא מממשת את כל‬
‫השיטות האבסטרקטיות‪ ,‬חייבת להיות אבסטרקטית בעצמה‪.‬‬
‫‪21‬‬
‫‪Spy Robot‬‬
‫• ‪( Spy Robot‬רובוט מעקב) הינו רובוט הנשלט מרחוק‬
‫ומאפשר צילום תמונות ושליחתן‪.‬‬
‫• רובוט מעקב יכול לבצע את הפעולות הבאות‪:‬‬
‫– לצלם תמונות ולשדר אותן‬
‫– לזוז קדימה ‪ /‬אחורה‬
‫– להסתובב ימינה ‪ /‬שמאלה‬
‫‪22‬‬
‫‪Spy Robot‬‬
‫• נסתכל על ‪ 2‬רובוטי מעקב‬
‫• שניהם יכולים לצלם תמונות ולשדר באותה דרך אך הם‬
‫זזים בדרכים שונות‪.‬‬
‫‪23‬‬
Spy Robot
public abstract class SpyRobot {
private String model;
public SpyRobot(String model) {
this.model=model;
}
public String getModel() {
return this.model;
}
public
public
public
public
abstract
abstract
abstract
abstract
void
void
void
void
moveForward();
moveBackward();
turnLeft();
turnRight();
public void takePicture() { ... }
public void chargeBattery() { ... }
}
24
Roboquad – Spy Robot
public class LegsSpyRobot extends SpyRobot {
public LegsSpyRobot() {
super("Roboquad");
}
public void moveForward() {
for(int i=0; i<4; i++)
this.moveLeg(i, 1);
}
public void moveBackward() {
for(int i=0; i<4; i++)
this.moveLeg(i, -1);
}
3
2
public void turnRight() {
public void turnLeft() {
this.moveLeg(0,1);
this.moveLeg(0,-1);
this.moveLeg(1,1);
this.moveLeg(1,-1);
this.moveLeg(2,-1);
this.moveLeg(2,1);
this.moveLeg(3,-1);
this.moveLeg(3,1);
}
}
// direction {1=forward, -1=backward}
private void moveLeg(int legId, int dir) { ... };
}
1
0
25
Spyke – Spy Robot
public class WheelsSpyRobot extends SpyRobot {
public WheelsSpyRobot() {
super("Spyke");
}
public void moveForward() {
this.turnWheels(1,1);
}
public void moveBackward() {
this.turnWheels(-1,-1);
}
public void turnLeft() {
this.turnWheels(0,-1);
}
public void turnRight() {
this.turnWheels(-1,0);
}
// direction {1=forward, 0=stop, -1=backward}
private void turnWheels(int rightDir,int leftDir) { ... };
// move features
public void waveHands() { ... }
}
26
‫‪Fly – Spy Robot‬‬
‫האם את זה אתם כבר יכולים לממש לבד ?‬
‫‪27‬‬
‫מחלקה אבסטרקטית‬
‫ממשק‬
‫לא ניתן ליצור מופעים‬
‫לא ניתן ליצור מופעים‬
‫שימוש ע"י ירושה (‪)extends‬‬
‫שימוש ע"י מימושו (‪)implements‬‬
‫יכולה להכיל קוד של חלק מהשיטות‬
‫הכרזה של שיטות בלי מימוש‬
‫יורשי מחלקה זו יהיו בעלי קוד משותף וכן בעלי‬
‫התנהגויות שונות (השיטות האבסטרקטיות)‬
‫ממשק הוא הכרזה על תכונה מופשטת‪,‬‬
‫למממשים אין קוד משותף‪.‬‬
‫מחלקה יכולה לרשת מחלקה (אבסטרקטית)‬
‫אחת בלבד‬
‫מחלקה יכולה לממש מספר ממשקים‬
‫אין הגבלה על שדות‬
‫רק קבועים סטאטיים (‪)implicitly‬‬
‫אין שיטות פרטיות‬
‫אין שיטות פרטיות‬
‫‪28‬‬
‫דוגמא נוספת‬
‫• נממש משחקים מתורת המשחקים ע"י הורשה‪:‬‬
‫– משחק מוגדר על ידי מערכת של פעולות אפשריות‬
‫ושיטת ניקוד‪.‬‬
‫– במשחק משחקים שני שחקנים כאשר שני השחקנים‬
‫בוחרים פעולה בו‪-‬זמנית‪.‬‬
‫– בהינתן שתי הבחירות של השחקנים יקבלו השחקנים‬
‫ניקוד ע"פ בחירתם‪.‬‬
‫‪29‬‬
‫דוגמה‪ :‬אבן נייר ומספריים‬
‫• בחירה מבין שלוש הפעולות האפשריות (אבן‪ ,‬נייר‬
‫או מספריים)‪.‬‬
‫– אבן שוברת מספריים‪.‬‬
‫– מספריים גוזרים נייר‪.‬‬
‫– נייר עוטף אבן‪.‬‬
‫‪30‬‬
‫‪http://www.youtube.com/watch?v=_PUEoDYpUyQ‬‬
‫המחלקות שעלינו לממש‬
‫• פעולה ‪Action‬‬
‫– שם הפעולה ("אבן")‬
‫• שחקן ‪Player‬‬
‫– שם השחקן (" ‪)" Andrea Farina‬‬
‫– מספר נקודות‬
‫– בחירת פעולה (מהלך) מתוך קבוצת פעולות אפשריות‪.‬‬
‫• משחק ‪Game‬‬
‫– קבוצת פעולות אפשריות‬
‫– שיטת ניקוד‬
‫– ‪ 2‬שחקנים‬
‫– שם המשחק‬
‫‪31‬‬
‫מימוש המחלקה של פעולה כללית‬
public class Action {
private String name;
public Action(String name) {
this.name = name;
}
public String getName(){
return this.name;
}
public boolean equals(Object other) {
boolean ans = false;
if(other instanceof Action)
ans = this.name.equals(((Action)other).name);
return ans;
}
}
32
‫מימוש המחלקה של שחקן כללי‬
public abstract class Player {
private String name;
private int score;
public Player(String name){
this.name = name;
this.score = 0;
}
public abstract Action selectAction(Action[] actions);
public boolean isWinner(Player p){
return (this.score > p.getScore());
}
public void updateScore(int score){
this.score = this.score + score;
}
public int getScore(){
return this.score;
}
}
33
‫מימוש שחקן אקראי‬
public class RandomPlayer extends Player{
public RandomPlayer(String name) {
super(name);
}
public Action selectAction(Action[] actions){
int randIdx = (int)(Math.random()*actions.length);
return actions[randIdx];
}
}
34
‫מימוש שחקן עיקבי‬
public class ConsecutivePlayer extends Player {
private int lastIdx;
public ConsecutivePlayer(String name) {
super(name);
this.lastIdx = 0;
}
public Action selectAction(Action[] actions) {
this.lastIdx = (this.lastIdx + 1) % actions.length;
return actions[this.lastIdx];
}
}
35
‫מימוש משחק כללי‬
public abstract class Game {
private Player p1, p2;
private String name;
//game name
protected Action[] actions; // the set of actions
public Game(Player p1, Player p2, String name){
this.p1 = p1;
this.p2 = p2;
this.name = name;
this.initActions();
}
// There is no real list of actions in a general game
protected abstract void initActions();
…
36
)‫כללי (המשך‬
‫מימוש משחק‬
public abstract class Game {
…
public void play(int turnCount) {
for (int i=0; i<turnCount; i=i+1)
this.playSingleTurn();
}
private void playSingleTurn() {
/* the selection order is not important
* as each player does not
* know the choice of the other player */
Action a1 = this.p1.selectAction(actions);
Action a2 = this.p2.selectAction(actions);
this.rewardPlayers(a1, a2);
}
// There is no real scoring strategy in a general game
protected abstract void rewardPlayers(Action a1, Action a2);
…
37
)‫כללי (המשך‬
‫מימוש משחק‬
public abstract class Game {
…
public Player getWinner () {
if (this.p1.isWinner(this.p2))
return this.p1;
else
return this.p2;
}
protected Player getFirstPlayer() {
return this.p1;
}
protected Player getSecondPlayer() {
return this.p2;
}
}
38
‫מימוש המשחק אבן נייר ומספריים‬
public class RockPaperScissors extends Game{
public RockPaperScissors(Player p1, Player p2) {
super(p1, p2, "Rock Paper Scissors");
}
protected void initActions(){
this.actions = new Action[3];
this.actions[0] = new Action("rock");
this.actions[1] = new Action("paper");
this.actions[2] = new Action("scissors");
}
...
39
protected void rewardPlayers(Action a1, Action a2) {
int p1score = 0;
if (!(a1.equals(a2))) {// Different actions
if ((a1.getName().equals("rock") &&
a2.getName().equals("scissors"))
|| (a1.getName().equals("paper") &&
a2.getName().equals("rock"))
|| (a1.getName().equals("scissors") &&
a2.getName().equals("paper"))) {
p1score = 1;
} else {
p1score = -1;
}
}
this.getFirstPlayer().updateScore(p1score);
this.getSecondPlayer().updateScore(-p1score);
}
}
40
‫דוגמה‪ :‬דילמת האסיר‬
‫•‬
‫•‬
‫•‬
‫•‬
‫המשטרה עוצרת שני עבריינים שביצעו פשע משותף‪ ,‬ומפרידה ביניהם‬
‫לצורך חקירה‪.‬‬
‫המשטרה מציעה לכל אחד מהם להעיד נגד רעהו‪ ,‬וכפרס מובטח לעד‬
‫עונש מופחת‪.‬‬
‫בחירה מבין הפעולות האפשריות‪ :‬להעיד או לשתוק‪.‬‬
‫ניקוד‪:‬‬
‫– אם שניהם יעידו‪ ,‬ייכנס כל אחד מהם לכלא לחמש שנים‪.‬‬
‫– אם רק אחד מהם יעיד ורעהו ישתוק‪ ,‬העד יצא מיד לחופשי וחברו ייכלא ל‪ 15-‬שנה‪.‬‬
‫– אם שניהם ישתקו‪ ,‬יכנס כל אחד מהם לשנה בכלא‪.‬‬
‫‪41‬‬
‫מימוש המשחק דילמת האסיר‬
public class PrisonerDilemmas extends Game{
public PrisonerDilemmas(Player p1, Player p2) {
super(p1, p2, "Prisoner's Dilemma");
}
protected void initActions(){
this.actions = new Action[2];
this.actions[0] = new Action("silent");
this.actions[1] = new Action("blame");
}
...
42
protected void rewardPlayers(Action a1, Action a2) {
if (a1.equals(a2)) { // Same actions
if (a1.getName().equals("blame") { // blame & blame
this.getFirstPlayer().updateScore(-5);
this.getSecondPlayer().updateScore(-5);
} else { // silent & silent
this.getFirstPlayer().updateScore(-1);
this.getSecondPlayer().updateScore(-1);
}
} else { // Different actions
if (a1.getName().equals("blame") { // blame & silent
this.getFirstPlayer().updateScore(0);
this.getSecondPlayer().updateScore(-15);
} else { // silent & blame
this.getFirstPlayer().updateScore(-15);
this.getSecondPlayer().updateScore(0);
}
}
}
}
43