Guest User

Untitled

a guest
Dec 30th, 2023
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 48.61 KB | None | 0 0
  1. using Microsoft.VisualBasic;
  2. using System.Text;
  3. using System.Text.Json;
  4.  
  5. namespace MestInt
  6. {
  7.     /// <summary>
  8.     /// Minden állapot osztály őse.
  9.     /// </summary>
  10.     public abstract class AbsztraktÁllapot : ICloneable
  11.     {
  12.         // Megvizsgálja, hogy a belső állapot állapot-e.
  13.         // Ha igen, akkor igazat ad vissza, egyébként hamisat.
  14.         public abstract bool ÁllapotE();
  15.         // Megvizsgálja, hogy a belső állapot célállapot-e.
  16.         // Ha igen, akkor igazat ad vissza, egyébként hamisat.
  17.         public abstract bool CélÁllapotE();
  18.         // Visszaadja az alapoperátorok számát.
  19.         public abstract int OperátorokSzáma();
  20.         // A szuper operátoron keresztül lehet elérni az összes operátort.
  21.         // Igazat ad vissza, ha az i.dik alap operátor alkalmazható a belső állapotra.
  22.         // for ciklusból kell hívni 0-tól kezdve az alap operátorok számig. Pl. így:
  23.         // for (int i = 0; i < állapot.GetNumberOfOps(); i++)
  24.         // {
  25.         // AbsztraktÁllapot klón=(AbsztraktÁllapot)állapot.Clone();
  26.         // if (klón.SzuperOperátor(i))
  27.         // {
  28.         // Console.WriteLine("Az {0} állapotra az {1}.dik " +
  29.         // "operátor alkalmazható", állapot, i);
  30.         // }
  31.         // }
  32.         public abstract bool SzuperOperátor(int i);
  33.         // Klónoz. Azért van rá szükség, mert némelyik operátor hatását vissza kell vonnunk.
  34.         // A legegyszerűbb, hogy az állapotot leklónozom. Arra hívom az operátort.
  35.         // Ha gond van, akkor visszatérek az eredeti állapothoz.
  36.         // Ha nincs gond, akkor a klón lesz az állapot, amiből folytatom a keresést.
  37.         // Ez sekély klónozást alkalmaz. Ha elég a sekély klónozás, akkor nem kell felülírni a gyermek osztályban.
  38.         // Ha mély klónozás kell, akkor mindenképp felülírandó.
  39.         public virtual object Clone() { return MemberwiseClone(); }
  40.         // Csak akkor kell felülírni, ha emlékezetes backtracket akarunk használni, vagy mélységi keresést.
  41.         // Egyébként maradhat ez az alap implementáció.
  42.         // Programozás technikailag ez egy kampó metódus, amit az OCP megszegése nélkül írhatok felül.
  43.         public override bool Equals(Object a) { return false; }
  44.         // Ha két példány egyenlő, akkor a hasítókódjuk is egyenlő.
  45.         // Ezért, ha valaki felülírja az Equals metódust, ezt is illik felülírni.
  46.         public override int GetHashCode() { return base.GetHashCode(); }
  47.     }
  48.  
  49.     public class Feladat_2_38 : AbsztraktÁllapot
  50.     {
  51.  
  52.         int ember1_testsúly;
  53.         int ember2_testsúly;
  54.         int ember3_testsúly;
  55.         int kő_súly;
  56.         int toronyban;
  57.         int földszinten;
  58.         int kosár1;
  59.         int kosár2;
  60.         bool kosár1_földszinten;
  61.         bool kosár2_földszinten;
  62.         public Feladat_2_38()
  63.         {
  64.  
  65.             ember1_testsúly = 78;
  66.             ember2_testsúly = 42;
  67.             ember3_testsúly = 36;
  68.             kő_súly = 30;
  69.             toronyban = 186;
  70.             földszinten = 0;
  71.             kosár1 = 0;
  72.             kosár2 = 0;
  73.             kosár1_földszinten = true;
  74.             kosár2_földszinten = false;
  75.         }
  76.        
  77.         public override bool CélÁllapotE()
  78.         {
  79.             //ember1, ember2, ember3 testsúlyának összege
  80.             return földszinten == 156 && kosár1_földszinten == true && kosár2_földszinten == false;
  81.         }
  82.  
  83.         public override int OperátorokSzáma()
  84.         {
  85.             //szuperoperátorok számának az összege
  86.             return 25;
  87.         }
  88.  
  89.         public override bool SzuperOperátor(int i)
  90.         {
  91.             switch (i)
  92.             {
  93.                 case 0: return kosár2_kő_be();
  94.                 case 1: return kosár1_ember3_be();
  95.                 case 2: return kosár2_kő_ki();
  96.                 case 3: return kosár1_ember3_ki();
  97.                 case 4: return kosár1_ember1_be();
  98.                 case 5: return kosár2_ember2_kő_be();
  99.                 case 6: return kosár2_ember2_ki();
  100.                 case 7: return kosár1_ember1_ki();
  101.                 case 8: return kosár1_ember3_be2();
  102.                 case 9: return kosár2_kő_ki2();
  103.                 case 10: return kosár2_ember2_be();
  104.                 case 11: return kosár1_ember3_ki2();
  105.                 case 12: return kosár2_ember2_ki2();
  106.                 case 13: return kosár1_kő_be();
  107.                 case 14: return kosár2_ember3_be();
  108.                 case 15: return kosár2_ember3_ki();
  109.                 case 16: return ujeset();
  110.                 case 17: return ujeset2();
  111.                 case 18: return ujeset3();
  112.                 case 19: return ujeset4();
  113.                 case 20: return ujeset5();
  114.                 case 21: return ujeset6();
  115.                 case 22: return ujeset7();
  116.                 case 24: return ujeset8();
  117.                 default: return false;
  118.                
  119.             }
  120.         }
  121.  
  122.         private bool ujeset8()
  123.         {
  124.             if (toronyban == 0 && kosár1 == 0 && kosár2 == 30 && kosár1_földszinten == true && kosár2_földszinten == false && földszinten == 156)
  125.             {
  126.                 kosár1_földszinten = true;
  127.                 kosár2_földszinten = false;
  128.             }
  129.  
  130.             else
  131.             {
  132.                 return false;
  133.             }
  134.  
  135.             return ÁllapotE();
  136.         }
  137.  
  138.         private bool ujeset7()
  139.         {
  140.             if (toronyban == 0 && kosár1 == 36 && kosár2 == 30 && kosár1_földszinten == false && kosár2_földszinten == true && földszinten == 120)
  141.             {
  142.                 kosár1 = kosár1 - ember3_testsúly;
  143.                 földszinten = földszinten + ember3_testsúly;
  144.                 kosár1_földszinten = true;
  145.                 kosár2_földszinten = false;
  146.             }
  147.  
  148.             else
  149.             {
  150.                 return false;
  151.             }
  152.  
  153.             return ÁllapotE();
  154.         }
  155.  
  156.         private bool ujeset6()
  157.         {
  158.             if (toronyban == 36 && kosár1 == 0 && kosár2 == 30 && kosár1_földszinten == false && kosár2_földszinten == true && földszinten == 120)
  159.             {
  160.                 kosár1 = kosár1 + ember3_testsúly;
  161.                 toronyban = toronyban - ember3_testsúly;
  162.                 kosár1_földszinten = true;
  163.                 kosár2_földszinten = false;
  164.             }
  165.  
  166.             else
  167.             {
  168.                 return false;
  169.             }
  170.  
  171.             return ÁllapotE();
  172.         }
  173.  
  174.         private bool ujeset5()
  175.         {
  176.             if (toronyban == 66 && kosár1 == 0 && kosár2 == 0 && kosár1_földszinten == true && kosár2_földszinten == false && földszinten == 120)
  177.             {
  178.                 kosár2 = kosár2 + kő_súly;
  179.                 toronyban = toronyban - kő_súly;
  180.                 kosár1_földszinten = false;
  181.                 kosár2_földszinten = true;
  182.             }
  183.  
  184.             else
  185.             {
  186.                 return false;
  187.             }
  188.  
  189.             return ÁllapotE();
  190.         }
  191.  
  192.         private bool ujeset4()
  193.         {
  194.             if (toronyban == 66 && kosár1 == 42 && kosár2 == 0 && kosár1_földszinten == true && kosár2_földszinten == false && földszinten == 78)
  195.             {
  196.                 kosár1 = kosár1 - ember2_testsúly;
  197.                 földszinten = földszinten + ember2_testsúly;
  198.                 kosár1_földszinten = true;
  199.                 kosár2_földszinten = false;
  200.             }
  201.  
  202.             else
  203.             {
  204.                 return false;
  205.             }
  206.  
  207.             return ÁllapotE();
  208.         }
  209.  
  210.         private bool ujeset3()
  211.         {
  212.             if (toronyban == 30 && kosár1 == 42 && kosár2 == 36 && kosár1_földszinten == true && kosár2_földszinten == false && földszinten == 78)
  213.             {
  214.                 kosár2 = kosár2 - ember3_testsúly;
  215.                 toronyban = toronyban + ember3_testsúly;
  216.                 kosár1_földszinten = true;
  217.                 kosár2_földszinten = false;
  218.             }
  219.  
  220.             else
  221.             {
  222.                 return false;
  223.             }
  224.  
  225.             return ÁllapotE();
  226.         }
  227.  
  228.         private bool ujeset2()
  229.         {
  230.             if (toronyban == 72 && kosár1 == 0 && kosár2 == 0 && kosár1_földszinten == false && kosár2_földszinten == true && földszinten == 114)
  231.             {
  232.                 kosár2 = kosár2 - ember3_testsúly;
  233.                 földszinten = földszinten - ember3_testsúly;
  234.                 kosár1 = kosár1 + ember2_testsúly;
  235.                 toronyban = toronyban - ember2_testsúly;
  236.                 kosár1_földszinten = true;
  237.                 kosár2_földszinten = false;
  238.             }
  239.  
  240.             else
  241.             {
  242.                 return false;
  243.             }
  244.  
  245.             return ÁllapotE();
  246.         }
  247.  
  248.         private bool ujeset()
  249.         {
  250.             if (toronyban == 72 && kosár1 == 0 && kosár2 == 36 && kosár1_földszinten == false && kosár2_földszinten == true && földszinten == 78)
  251.             {
  252.                 kosár2 = kosár2 - ember3_testsúly;
  253.                 földszinten = földszinten + ember3_testsúly;
  254.                 kosár1_földszinten = false;
  255.                 kosár2_földszinten = true;
  256.             }
  257.  
  258.             else
  259.             {
  260.                 return false;
  261.             }
  262.  
  263.             return ÁllapotE();
  264.         }
  265.  
  266.         private bool kosár2_ember3_ki()
  267.         {
  268.             if (toronyban == 42 && kosár1 == 30 && kosár2 == 36 && kosár1_földszinten == false && kosár2_földszinten == true && földszinten == 78)
  269.                 {
  270.                     kosár1 = kosár1 - kő_súly;
  271.                     toronyban = toronyban + kő_súly;
  272.                     kosár1_földszinten = false;
  273.                     kosár2_földszinten = true;
  274.                     return true;
  275.                 }
  276.  
  277.             return ÁllapotE();
  278.         }
  279.  
  280.         private bool kosár2_ember3_be()
  281.         {
  282.             if (toronyban == 78 && kosár1 == 30 && kosár2 == 0 && kosár1_földszinten == true && kosár2_földszinten == false && földszinten == 78)
  283.             {
  284.                 kosár2 = kosár2 + ember3_testsúly;
  285.                 toronyban = toronyban - ember3_testsúly;
  286.                 kosár1_földszinten = false;
  287.                 kosár2_földszinten = true;
  288.             }
  289.             else
  290.             {
  291.                 return false;
  292.             }
  293.             return ÁllapotE();
  294.         }
  295.  
  296.         private bool kosár1_kő_be()
  297.         {
  298.             if (toronyban == 108 && kosár1 == 0 && kosár2 == 0 && kosár1_földszinten == false && kosár2_földszinten == true && földszinten == 78)
  299.             {
  300.                 kosár1 = kosár1 + kő_súly;
  301.                 toronyban = toronyban - kő_súly;
  302.                 kosár1_földszinten = true;
  303.                 kosár2_földszinten = false;
  304.  
  305.             }
  306.             else
  307.             {
  308.                 return false;
  309.             }
  310.  
  311.             return ÁllapotE();
  312.         }
  313.  
  314.         private bool kosár2_ember2_ki2()
  315.         {
  316.             if (toronyban == 108 && kosár1 == 0 && kosár2 == 78 && kosár1_földszinten == false && kosár2_földszinten == true && földszinten == 0)
  317.             {
  318.                 kosár2 = kosár2 - ember1_testsúly;
  319.                 földszinten = földszinten + ember1_testsúly;
  320.                 kosár1_földszinten = false;
  321.                 kosár2_földszinten = true;
  322.  
  323.             }
  324.             else
  325.             {
  326.                 return false;
  327.             }
  328.  
  329.             return ÁllapotE();
  330.         }
  331.  
  332.         private bool kosár1_ember3_ki2()
  333.         {
  334.             if (toronyban == 36 && kosár1 == 72 && kosár2 == 78 && kosár1_földszinten == false && kosár2_földszinten == true && földszinten == 0)
  335.             {
  336.                 kosár1 = (kosár1 - ember2_testsúly) - kő_súly;
  337.                 toronyban = (toronyban + ember2_testsúly) + kő_súly;
  338.                 kosár1_földszinten = false;
  339.                 kosár2_földszinten = true;
  340.             }
  341.             else
  342.             {
  343.                 return false;
  344.             }
  345.  
  346.             return ÁllapotE();
  347.         }
  348.  
  349.         private bool kosár2_ember2_be()
  350.         {
  351.             if (toronyban == 114 && kosár1 == 72 && kosár2 == 0 && kosár1_földszinten == true && kosár2_földszinten == false && földszinten == 0)
  352.             {
  353.                 kosár2 = kosár2 + ember1_testsúly;
  354.                 toronyban = toronyban - ember1_testsúly;
  355.                 kosár1_földszinten = false;
  356.                 kosár2_földszinten = true;
  357.             }
  358.             else
  359.             {
  360.                 return false;
  361.             }
  362.  
  363.            
  364.             return ÁllapotE();
  365.         }
  366.  
  367.         private bool kosár2_kő_ki2()
  368.         {
  369.             if (toronyban == 114 && kosár1 == 30 && kosár2 == 0 && kosár1_földszinten == true && kosár2_földszinten == false && földszinten == 42)
  370.             {
  371.                 kosár1 = kosár1 + ember2_testsúly;
  372.                 földszinten = földszinten - ember2_testsúly;
  373.                 kosár1_földszinten = true;
  374.                 kosár2_földszinten = false;
  375.             }
  376.             else
  377.             {
  378.                 return false;
  379.             }
  380.  
  381.             return ÁllapotE();
  382.         }
  383.  
  384.         private bool kosár1_ember3_be2()
  385.         {
  386.             if (toronyban == 144 && kosár1 == 0 && kosár2 == 0 && kosár1_földszinten == false && kosár2_földszinten == true && földszinten == 42)
  387.             {
  388.                 kosár1 = kosár1 + kő_súly;
  389.                 toronyban = toronyban - kő_súly;
  390.                 kosár1_földszinten = true;
  391.                 kosár2_földszinten = false;
  392.             }
  393.             else
  394.             {
  395.                 return false;
  396.             }
  397.  
  398.            
  399.             return ÁllapotE();
  400.         }
  401.  
  402.         private bool kosár1_ember1_ki()
  403.         {
  404.             if (toronyban == 144 && kosár1 == 0 && kosár2 == 42 && kosár1_földszinten == true && kosár2_földszinten == false && földszinten == 0)
  405.             {
  406.                 kosár2 = kosár2 - ember2_testsúly;
  407.                 földszinten = földszinten + ember2_testsúly;
  408.                 kosár1_földszinten = false;
  409.                 kosár2_földszinten = true;
  410.          
  411.             }
  412.             else
  413.             {
  414.                 return false;
  415.             }
  416.  
  417.            
  418.             return ÁllapotE();
  419.         }
  420.  
  421.         private bool kosár2_ember2_ki()
  422.         {
  423.             if (toronyban == 108 && kosár1 == 36 && kosár2 == 42 && kosár1_földszinten == false && kosár2_földszinten == true && földszinten == 0)
  424.             {
  425.                 kosár1 = kosár1 - ember3_testsúly;
  426.                 toronyban = toronyban + ember3_testsúly;
  427.                 kosár1_földszinten = true;
  428.                 kosár2_földszinten = false;
  429.  
  430.             }
  431.             else
  432.             {
  433.                 return false;
  434.             }
  435.                
  436.                
  437.            
  438.             return ÁllapotE();
  439.         }
  440.  
  441.         private bool kosár2_ember2_kő_be()
  442.         {
  443.             if (toronyban == 150 && kosár1 == 36 && kosár2 == 0 && kosár1_földszinten == true && kosár2_földszinten == false && földszinten == 0)
  444.             {
  445.                 kosár2 = kosár2 + ember2_testsúly;
  446.                 toronyban = toronyban - ember2_testsúly;
  447.                 kosár1_földszinten = false;
  448.                 kosár2_földszinten = true;
  449.             }
  450.             else
  451.             {
  452.                 return false;
  453.             }
  454.  
  455.            
  456.             return ÁllapotE();
  457.         }
  458.  
  459.         private bool kosár1_ember1_be()
  460.         {
  461.             if (toronyban == 150 && kosár1 == 0 && kosár2 == 0 && kosár1_földszinten == false && kosár2_földszinten == true && földszinten == 36)
  462.             {
  463.                 kosár1 = kosár1 + ember3_testsúly;
  464.                 földszinten = földszinten - ember3_testsúly;
  465.                 kosár1_földszinten = true;
  466.                 kosár2_földszinten = false;
  467.             }
  468.             else
  469.             {
  470.                 return false;
  471.             }
  472.  
  473.  
  474.            
  475.             return ÁllapotE();
  476.         }
  477.  
  478.         private bool kosár1_ember3_ki()
  479.         {
  480.             if (toronyban == 150 && kosár1 == 36 && kosár2 == 0 && kosár1_földszinten == true && kosár2_földszinten == false && földszinten == 0)
  481.             {
  482.                 kosár1 = kosár1 - ember3_testsúly;
  483.                 földszinten = földszinten + ember3_testsúly;
  484.                 kosár1_földszinten = false;
  485.                 kosár2_földszinten = true;
  486.             }
  487.             else
  488.             {
  489.                 return false;
  490.             }
  491.                
  492.            
  493.             return ÁllapotE();
  494.         }
  495.  
  496.         private bool kosár2_kő_ki()
  497.         {
  498.             if (toronyban == 120 && kosár1 == 36 && kosár2 == 30 && kosár1_földszinten == true && kosár2_földszinten == false && földszinten == 0)
  499.             {
  500.                 kosár2 = kosár2 - kő_súly;
  501.                 toronyban = toronyban + kő_súly;
  502.                 kosár1_földszinten = true;
  503.                 kosár2_földszinten = false;
  504.             }
  505.             else
  506.             {
  507.                 return false;
  508.             }  
  509.  
  510.             return ÁllapotE();
  511.         }
  512.  
  513.         private bool kosár1_ember3_be()
  514.         {
  515.             if (toronyban == 156 && kosár1 == 0 && kosár2 == 30 && kosár1_földszinten == false && kosár2_földszinten == true && földszinten == 0)
  516.             {
  517.                 toronyban = toronyban - ember3_testsúly;
  518.                 kosár1 = kosár1 + ember3_testsúly;
  519.  
  520.                 kosár1_földszinten = true;
  521.                 kosár2_földszinten = false;
  522.                
  523.             }
  524.             else
  525.             {
  526.                 return false;
  527.             }
  528.  
  529.  
  530.             return ÁllapotE();
  531.  
  532.         }
  533.  
  534.         private bool kosár2_kő_be()
  535.         {
  536.             if (toronyban == 186 && kosár1_földszinten == true && kosár2_földszinten == false && kosár1 == 0 && kosár2 == 0 && földszinten == 0)
  537.             {
  538.                 kosár2 = kosár2 + kő_súly;
  539.                 toronyban = toronyban - kő_súly;
  540.                 kosár2_földszinten = true;
  541.                 kosár1_földszinten = false;
  542.             }
  543.             else
  544.             {
  545.                 return false;
  546.             }
  547.  
  548.             return ÁllapotE();
  549.         }
  550.  
  551.         public override bool ÁllapotE()
  552.         {
  553.             return toronyban >= 0 && Math.Abs(kosár1 - kosár2) >= 6 && toronyban <= 186;
  554.         }
  555.  
  556.         public override string ToString()
  557.         {
  558.             StringBuilder sb = new StringBuilder();
  559.             sb.Append("földszint: ");
  560.             sb.Append(földszinten);
  561.             sb.Append(" torony: ");
  562.             sb.Append(toronyban);
  563.             sb.Append(" kosár1: " );
  564.             sb.Append(kosár1);
  565.             sb.Append(" kosár 2: ");
  566.             sb.Append(kosár2);
  567.  
  568.             return sb.ToString();
  569.         }
  570.     }
  571.  
  572.  
  573.     //probléma redukció: természetes megoldási
  574.     //először is van egy célom
  575.     //a következő részt célt azt úgy érem el hogy amit eddig csináltam azt nem rontom el
  576.     public class Feladat_1_3 : AbsztraktÁllapot
  577.     {
  578.         int[,] tábla = { {1,5,3,4,3,6,7,1,1,6 },
  579.                         {4,4,3,4,2,6,2,6,2,5 },
  580.                         {1,3,9,4,5,2,4,2,9,5 },
  581.                         {5,2,3,5,5,6,4,6,2,4 },
  582.                         {1,3,3,2,5,6,5,2,3,2 },
  583.                         {2,5,2,5,5,6,4,8,6,1 },
  584.                         {9,2,3,6,5,6,2,2,2,0 } };
  585.  
  586.         int figX, figY;
  587.  
  588.         public Feladat_1_3() { figX = 0; figY = 0; }
  589.         public override bool CélÁllapotE()
  590.         {
  591.             //return figX == 6 && figY == 9;
  592.             return tábla[figX, figY] == 0;
  593.         }
  594.  
  595.         public override int OperátorokSzáma()
  596.         {
  597.             return 8;
  598.         }
  599.  
  600.         public override bool SzuperOperátor(int i)
  601.         {
  602.             switch (i)
  603.             {
  604.                 case 0: return lépés(0, 1);
  605.                 case 1: return lépés(0, -1);
  606.                 case 2: return lépés(1, 0);
  607.                 case 3: return lépés(-1, 0);
  608.                 case 4: return lépés(1, 1);
  609.                 case 5: return lépés(-1, -1);
  610.                 case 6: return lépés(-1, 1);
  611.                 case 7: return lépés(1, -1);
  612.  
  613.                 default : return false;
  614.             }
  615.         }
  616.         private bool lépés(int xirány, int yirány)
  617.         {
  618.             //előfeltétel
  619.             //if(!preLépés(xirány,yirány)) return false;
  620.             //állapot átmenet
  621.             int lépésSzám = tábla[figX, figY];
  622.             figX += lépésSzám * xirány;
  623.             figY += lépésSzám * yirány;
  624.             //utófeltétel
  625.             if (ÁllapotE()) return true; else return false;
  626.         }
  627.         public override bool ÁllapotE()
  628.         {
  629.             return figX >= 0 && figX <= 6 && figY >=0 && figY <=9;
  630.                    
  631.         }
  632.  
  633.         //klónozást nem kell felülírni, habár van tömb de az nem változik, két int mező van, e miatt nem kell klónozás
  634.         //viszont lehet kör, e miatt Equals-t felül kell írni kiíratáshoz
  635.  
  636.         public override bool Equals(object a)
  637.         {
  638.             //típus kényszerítés
  639.             Feladat_1_3 másik = a as Feladat_1_3;
  640.             //minden mezőnek egyenlőnek kell lenni
  641.             return this.figX == másik.figX && this.figY == másik.figY;
  642.         }
  643.  
  644.         public override string ToString()
  645.         {
  646.             StringBuilder sb = new StringBuilder();
  647.             sb.Append("figX=");
  648.             sb.Append(figX);
  649.             sb.Append(", figY=");
  650.             sb.Append(figY);
  651.             sb.Append(", tábla [figX, figY]=");
  652.             sb.Append(tábla[figX, figY]);
  653.             return sb.ToString();
  654.         }
  655.     }
  656.  
  657.     public class Feladat2p8 : AbsztraktÁllapot
  658.     {
  659.         //kezdoállapot
  660.         int[,] tábla = { {2,3,4,5,1},
  661.                         {6,7,8,9,10},
  662.                         {11,12,13,14,15},
  663.                         {16,17,18,19,20},
  664.                         {21,22,23,24,25}
  665.                    };
  666.  
  667.         public int[,] GetTábla() { return tábla; }
  668.  
  669.         int[,] céltábla = { {1,2,3,4,5},
  670.                         {6,7,8,9,10},
  671.                         {11,12,13,14,15},
  672.                         {16,17,18,19,20},
  673.                         {21,22,23,24,25}
  674.                       };
  675.         public override bool CélÁllapotE()
  676.         {
  677.             for (int i = 0; i < tábla.GetLength(0); i++)
  678.             {
  679.                 for (int j = 0; j < tábla.GetLength(1); j++)
  680.                 {
  681.                     //ha a két aktuális elem nem egyenlő return false
  682.                     if (tábla[i, j] != céltábla[i, j])
  683.                         return false;
  684.                 }
  685.             }
  686.             return true;
  687.         }
  688.  
  689.         public override int OperátorokSzáma()
  690.         {
  691.             return 20;
  692.         }
  693.  
  694.         public override bool SzuperOperátor(int i)
  695.         {
  696.             switch (i)
  697.             {
  698.                 case 0: return forgatBalra(0);
  699.                 case 1: return forgatBalra(1);
  700.                 case 2: return forgatBalra(2);
  701.                 case 3: return forgatBalra(3);
  702.                 case 4: return forgatBalra(4);
  703.  
  704.                 case 5: return forgatJobbra(0);
  705.                 case 6: return forgatJobbra(1);
  706.                 case 7: return forgatJobbra(2);
  707.                 case 8: return forgatJobbra(3);
  708.                 case 9: return forgatJobbra(4);
  709.  
  710.                 case 10: return forgatFel(0);
  711.                 case 11: return forgatFel(1);
  712.                 case 12: return forgatFel(2);
  713.                 case 13: return forgatFel(3);
  714.                 case 14: return forgatFel(4);
  715.  
  716.                 case 15: return forgatLe(0);
  717.                 case 16: return forgatLe(1);
  718.                 case 17: return forgatLe(2);
  719.                 case 18: return forgatLe(3);
  720.                 case 19: return forgatLe(4);
  721.  
  722.                 default: return false;
  723.             }
  724.         }
  725.  
  726.         public override bool ÁllapotE()
  727.         {
  728.             return true;
  729.         }
  730.         // Nem biztos hogy jól csináltuk, csináljunk unit tesztet
  731.         // A unit teszt a metódusok tesztje
  732.         // Ehhez szükséges egy unit teszt framework (java: JUNIT5, c#: MSTEST, NTEST)
  733.         // A lépések nem intuitívak.
  734.         // [TestMethod]
  735.         // Minden unit testben 5 dolog van: target, fix paraméterek, expected value(elvárt), actual value(aktuális érték), és a kettő összehasonlítása
  736.         // target:: tesztelendő cucc egy példánya
  737.  
  738.  
  739.         public bool forgatBalra(int sor)
  740.         {
  741.             int elsőElem = tábla[sor, 0];
  742.             for (int i = 1; i < tábla.GetLength(1); i++)
  743.             {
  744.                 tábla[sor, i - 1] = tábla[sor, i];
  745.             }
  746.             tábla[sor, tábla.GetLength(1) - 1] = elsőElem;
  747.             return true;
  748.         }
  749.         public bool forgatJobbra(int sor)
  750.         {
  751.             int utolsóElem = tábla[sor, tábla.GetLength(1) - 1];
  752.             for (int i = tábla.GetLength(1) - 2; i >= 0; i--)
  753.             {
  754.                 tábla[sor, i + 1] = tábla[sor, i];
  755.             }
  756.             tábla[sor, 0] = utolsóElem;
  757.             return true;
  758.         }
  759.         public bool forgatFel(int oszlop)
  760.         {
  761.             int felsoElem = tábla[0, oszlop];
  762.             for (int i = 1; i < tábla.GetLength(0); i++)
  763.             {
  764.                 tábla[i - 1, oszlop] = tábla[i, oszlop];
  765.             }
  766.             tábla[tábla.GetLength(0) - 1, oszlop] = felsoElem;
  767.             return true;
  768.         }
  769.         public bool forgatLe(int oszlop)
  770.         {
  771.             int alsoElem = tábla[tábla.GetLength(0) - 1, oszlop];
  772.             for (int i = tábla.GetLength(0) - 2; i >= 0; i--)
  773.             {
  774.                 tábla[i + 1, oszlop] = tábla[i, oszlop];
  775.             }
  776.             tábla[0, oszlop] = alsoElem;
  777.             return true;
  778.         }
  779.         public override object Clone()
  780.         {
  781.             Feladat2p8 myClone = new Feladat2p8();
  782.             myClone.tábla = this.tábla.Clone() as int[,];
  783.             return myClone;
  784.         }
  785.         public override bool Equals(object? a)
  786.         {
  787.             Feladat2p8 másik = a as Feladat2p8;
  788.             return másik.tábla.Equals(this.tábla);
  789.         }
  790.         class Macska
  791.         {
  792.             string név;
  793.             double éhség;
  794.             string[] csíkok;
  795.             public override bool Equals(object? obj)
  796.             {
  797.                 Macska másik = obj as Macska;
  798.                 return másik.név == this.név &&
  799.                        másik.éhség == this.éhség &&
  800.                        másik.csíkok.Equals(this.csíkok);
  801.             }
  802.         }
  803.         // Ha elképzelhető hogy visszajutok ugyanabba az állapotba akkor felül kell írni az Equals-t is
  804.         // Ez végtelen ciklust okozhat
  805.         // Minden mezőt fel kell használni
  806.         // Két objektum akkor egyenlő ha minden mezőjük egyenlő
  807.         public override string ToString()
  808.         {
  809.             //minden mezőt fel kell használni
  810.             StringBuilder sb = new StringBuilder();
  811.             for(int i = 0;i<tábla.GetLength(0);i++)
  812.             {
  813.                 for (int j = 0; j < tábla.GetLength(1); j++)
  814.                 {
  815.                     sb.Append(tábla[i, j]);
  816.                     sb.Append(" ");
  817.                 }
  818.                 sb.Append('\n');
  819.             }
  820.             return sb.ToString();
  821.         }
  822.     }
  823.  
  824.     class Feladat2p5 : AbsztraktÁllapot
  825.     {
  826.         int alma, körte, barack;
  827.         public Feladat2p5()
  828.         {
  829.             alma = 1;
  830.             körte = 1;
  831.             barack = 59;
  832.         }
  833.  
  834.         public override bool CélÁllapotE()
  835.         {
  836.             return (alma == 0 && körte == 0) ||
  837.                    (alma == 0 && barack == 0) ||
  838.                    (barack == 0 && körte == 0);
  839.         }
  840.  
  841.         public override int OperátorokSzáma()
  842.         {
  843.             //egy almát és egy körtét 2 barackra
  844.             //egy almát és egy barackot 2 körtére
  845.             //egy körtét és egy barackor 2 almára
  846.             return 3;
  847.         }
  848.  
  849.         public override bool SzuperOperátor(int i)
  850.         {
  851.             switch (i)
  852.             {
  853.                 case 0: return barackra();
  854.                 case 1: return körtére();
  855.                 case 2: return almára();
  856.                 default: return false;
  857.             }
  858.         }
  859.  
  860.         private bool barackra()
  861.         {
  862.             if (alma == 0 || körte == 0) return false;
  863.             alma--;
  864.             körte--;
  865.             barack += 2;
  866.             return ÁllapotE();
  867.         }
  868.  
  869.         private bool körtére()
  870.         {
  871.             if (alma == 0 || barack == 0) return false;
  872.             alma--;
  873.             barack--;
  874.             körte += 2;
  875.             return ÁllapotE();
  876.         }
  877.  
  878.         private bool almára()
  879.         {
  880.             if (barack == 0 || körte == 0) return false;
  881.             barack--;
  882.             körte--;
  883.             alma += 2;
  884.             return ÁllapotE();
  885.         }
  886.  
  887.         public override bool ÁllapotE()
  888.         {
  889.             return alma >= 0 && körte >= 0 && barack >= 0;
  890.         }
  891.  
  892.         public override string ToString()
  893.         {
  894.             //minden mezőt fel kell használni
  895.             StringBuilder sb = new StringBuilder();
  896.             sb.Append("alma= ").Append(alma)
  897.                 .Append(", körte= ").Append(körte)
  898.                 .Append(", barack= ").Append(barack);
  899.  
  900.             return sb.ToString();
  901.         }
  902.     }
  903.  
  904.     class DieHardProbléma : AbsztraktÁllapot
  905.     {
  906.         int jug3G, jug5G;
  907.         public DieHardProbléma()
  908.         {
  909.             jug3G = 0;
  910.             jug5G = 0;
  911.         }
  912.  
  913.         public override bool CélÁllapotE()
  914.         {
  915.             return jug5G == 4;
  916.         }
  917.  
  918.         public override int OperátorokSzáma()
  919.         {
  920.             //teletöltöm a 3G-st
  921.             //kiöntok mindent a 3G-ből
  922.             //áttöltök 3G-ből 5G-be
  923.             //teletöltöm a 5G-st
  924.             //kiöntok mindent a 5G-ből
  925.             //áttöltök 5G-ből
  926.             //megoldás: 5G tele, át 3g-be, 3g ürít, 5g-ben maradt 2 át 3g-be, 5g tele, 1g fér át a 3-asba marad 4
  927.             return 3;
  928.         }
  929.  
  930.         public override bool SzuperOperátor(int i)
  931.         {
  932.             switch (i)
  933.             {
  934.                 case 0: return tele5G();
  935.                 case 1: return urit3G();
  936.                 case 2: return át5ből3ba();
  937.                 default: return false;
  938.             }
  939.         }
  940.  
  941.         private bool tele5G()
  942.         {
  943.             //if (!preTele5G()) return false;
  944.             if (jug5G == 5) return false;
  945.             //állapotátmenet
  946.             jug5G = 5;
  947.             //if(!ÁllapotE()) return false;
  948.             return true;
  949.         }
  950.  
  951.         private bool urit3G()
  952.         {
  953.             if (jug3G == 0) return false;
  954.             jug3G = 0;
  955.             return true;
  956.         }
  957.  
  958.         private bool át5ből3ba()
  959.         {
  960.             if (jug3G == 3 || jug5G == 0) return false;
  961.             int hely3ban = 3 - jug3G;
  962.             if (hely3ban >= jug5G) hely3ban = jug5G;
  963.             jug5G -= hely3ban;
  964.             jug3G += hely3ban;
  965.             return true;
  966.         }
  967.  
  968.         public override bool ÁllapotE()
  969.         {
  970.             return jug3G >= 0 && jug5G >= 0 &&
  971.                    jug3G <= 3 && jug5G <= 5;
  972.         }
  973.  
  974.         public override string ToString()
  975.         {
  976.             //minden mezőt fel kell használni
  977.             return "jug3G=" + jug3G + "jug5G=" + jug5G;
  978.         }
  979.     }
  980.  
  981.  
  982.     //8.4.1
  983.     /// <summary>
  984.     /// A "3 szerzetes és 3 kannibál" probléma állapottér reprezentációja.
  985.     /// Illetve általánosítása akárhány szerzetesre és kannibálra.
  986.     /// Probléma: 3 szerzet és 3 kannibál van a folyó bal partján.
  987.     /// Át kell juttatni az összes embert a másik partra.
  988.     /// Ehhez rendelkezésre áll egy két személyes csónak.
  989.     /// Egy ember is elég az átjutáshoz, de kettőnél több ember nem fér el.
  990.     /// Ha valaki átmegy a másik oldalra, akkor ki is kell szállni, nem maradhat a csónakban.
  991.     /// A gond ott van, hogy ha valamelyik parton több kannibál van,
  992.     /// mint szerzetes, akkor a kannibálok megeszik a szerzeteseket.
  993.     /// Kezdő állapot:
  994.     /// 3 szerzetes a bal oldalon.
  995.     /// 3 kannibál a bal oldalon.
  996.     /// A csónak a bal parton van.
  997.     /// 0 szerzetes a jobb oldalon.
  998.     /// 0 kannibál a jobb oldalon.
  999.     /// Ezt az állapotot ezzel a rendezett 5-össel írjuk le:
  1000.     /// (3,3,'B',0,0)
  1001.     /// A célállapot:
  1002.     /// (0,0,'J',3,3)
  1003.     /// Operátor:
  1004.     /// Op(int sz, int k):
  1005.     /// sz darab szerzetes átmegy a másik oldalra és
  1006.     /// k darab kannibál átmegy a másik oldalra.
  1007.     /// Lehetséges paraméterezése:
  1008.     /// Op(1,0): 1 szerzetes átmegy a másik oldalra.
  1009.     /// Op(2,0): 2 szerzetes átmegy a másik oldalra.
  1010.     /// Op(1,1): 1 szerzetes és 1 kannibál átmegy a másik oldalra.
  1011.     /// Op(0,1): 1 kannibál átmegy a másik oldalra.
  1012.     /// Op(0,2): 2 kanibál átmegy a másik oldalra.
  1013.     /// </summary>
  1014.     class SzerzetesekÉsKannibálokÁllapot : AbsztraktÁllapot
  1015.     {
  1016.         int sz; // ennyi szerzetes van összesen
  1017.         int k; // ennyi kannibál van összesen
  1018.         int szb; // szerzetesek száma a bal oldalon
  1019.         int kb; // kannibálok száma a bal oldalon
  1020.         char cs; // Hol a csónak? Értéke vagy 'B' vagy 'J'.
  1021.         int szj; // szerzetesek száma a jobb oldalon
  1022.         int kj; // kannibálok száma a jobb oldalon
  1023.         public SzerzetesekÉsKannibálokÁllapot(int sz, int k) // beállítja a kezdő állapotot
  1024.         {
  1025.             this.sz = sz;
  1026.             this.k = k;
  1027.             szb = sz;
  1028.             kb = k;
  1029.             cs = 'B';
  1030.             szj = 0;
  1031.             kj = 0;
  1032.         }
  1033.         public override bool ÁllapotE()
  1034.         { // igaz, ha a szerzetesek biztonságban vannak
  1035.             return ((szb >= kb) || (szb == 0)) &&
  1036.             ((szj >= kj) || (szj == 0));
  1037.         }
  1038.         public override bool CélÁllapotE()
  1039.         {
  1040.             // igaz, ha mindenki átért a jobb oldalra
  1041.             return szj == sz && kj == k;
  1042.         }
  1043.         private bool preOp(int sz, int k)
  1044.         {
  1045.             // A csónak 2 személyes, legalább egy ember kell az evezéshez.
  1046.             // Ezt végül is felesleges vizsgálni, mert a szuper operátor csak ennek megfelelően hívja.
  1047.             if (sz + k > 2 || sz + k < 0 || sz < 0 || k < 0) return false;
  1048.             // Csak akkor lehet átvinni sz szerzetest és
  1049.             // k kannibált, ha a csónak oldalán van is legalább ennyi.
  1050.             if (cs == 'B')
  1051.                 return szb >= sz && kb >= k;
  1052.             else
  1053.                 return szj >= sz && kj >= k;
  1054.         }
  1055.         // Átvisz a másik oldalra sz darab szerzetes és k darab kannibált.
  1056.         private bool op(int sz, int k)
  1057.         {
  1058.             if (!preOp(sz, k)) return false;
  1059.             SzerzetesekÉsKannibálokÁllapot mentes = (SzerzetesekÉsKannibálokÁllapot)Clone();
  1060.             if (cs == 'B')
  1061.             {
  1062.                 szb -= sz;
  1063.                 kb -= k;
  1064.                 cs = 'J';
  1065.                 szj += sz;
  1066.                 kj += k;
  1067.             }
  1068.             else
  1069.             {
  1070.                 szb += sz;
  1071.                 kb += k;
  1072.                 cs = 'B';
  1073.                 szj -= sz;
  1074.                 kj -= k;
  1075.             }
  1076.             if (ÁllapotE()) return true;
  1077.             szb = mentes.szb;
  1078.             kb = mentes.kb;
  1079.             cs = mentes.cs;
  1080.             szj = mentes.szj;
  1081.             kj = mentes.kj;
  1082.             return false;
  1083.         }
  1084.         public override int OperátorokSzáma() { return 5; }
  1085.         public override bool SzuperOperátor(int i)
  1086.         {
  1087.             switch (i)
  1088.             {
  1089.                 case 0: return op(0, 1);
  1090.                 case 1: return op(0, 2);
  1091.                 case 2: return op(1, 1);
  1092.                 case 3: return op(1, 0);
  1093.                 case 4: return op(2, 0);
  1094.                 default: return false;
  1095.             }
  1096.         }
  1097.         public override string ToString()
  1098.         {
  1099.             return szb + "," + kb + "," + cs + "," + szj + "," + kj;
  1100.         }
  1101.         public override bool Equals(Object a)
  1102.         {
  1103.             SzerzetesekÉsKannibálokÁllapot aa = (SzerzetesekÉsKannibálokÁllapot)a;
  1104.             // szj és kj számítható, ezért nem kell vizsgálni
  1105.             return aa.szb == szb && aa.kb == kb && aa.cs == cs;
  1106.         }
  1107.         // Ha két példány egyenlő, akkor a hasítókódjuk is egyenlő.
  1108.         public override int GetHashCode()
  1109.         {
  1110.             return szb.GetHashCode() + kb.GetHashCode() + cs.GetHashCode();
  1111.         }
  1112.     }
  1113.  
  1114.     //8.5.1
  1115.     /// <summary>
  1116.     /// A csúcs tartalmaz egy állapotot, a csúcs mélységét, és a csúcs szülőjét.
  1117.     /// Így egy csúcs egy egész utat reprezentál a start csúcsig.
  1118.     /// </summary>
  1119.     class Csúcs
  1120.     {
  1121.         // A csúcs tartalmaz egy állapotot, a mélységét és a szülőjét
  1122.         AbsztraktÁllapot állapot;
  1123.         int mélység;
  1124.         Csúcs szülő; // A szülőkön felfelé haladva a start csúcsig jutok.
  1125.                      // Konstruktor:
  1126.                      // A belső állapotot beállítja a start csúcsra.
  1127.                      // A hívó felelőssége, hogy a kezdő állapottal hívja meg.
  1128.                      // A start csúcs mélysége 0, szülője nincs.
  1129.         public Csúcs(AbsztraktÁllapot kezdőÁllapot)
  1130.         {
  1131.             állapot = kezdőÁllapot;
  1132.             mélység = 0;
  1133.             szülő = null;
  1134.         }
  1135.         // Egy új gyermek csúcsot készít.
  1136.         // Erre még meg kell hívni egy alkalmazható operátor is, csak azután lesz kész.
  1137.         public Csúcs(Csúcs szülő)
  1138.         {
  1139.             állapot = (AbsztraktÁllapot)szülő.állapot.Clone();
  1140.             mélység = szülő.mélység + 1;
  1141.             this.szülő = szülő;
  1142.         }
  1143.         public Csúcs GetSzülő() { return szülő; }
  1144.         public int GetMélység() { return mélység; }
  1145.         public bool TerminálisCsúcsE() { return állapot.CélÁllapotE(); }
  1146.         public int OperátorokSzáma() { return állapot.OperátorokSzáma(); }
  1147.         public bool SzuperOperátor(int i) { return állapot.SzuperOperátor(i); }
  1148.         public override bool Equals(Object obj)
  1149.         {
  1150.             Csúcs cs = (Csúcs)obj;
  1151.             return állapot.Equals(cs.állapot);
  1152.         }
  1153.         public override int GetHashCode() { return állapot.GetHashCode(); }
  1154.         public override String ToString() { return állapot.ToString(); }
  1155.         // Alkalmazza az összes alkalmazható operátort.
  1156.         // Visszaadja az így előálló új csúcsokat.
  1157.         public List<Csúcs> Kiterjesztes()
  1158.         {
  1159.             List<Csúcs> újCsúcsok = new List<Csúcs>();
  1160.             for (int i = 0; i < OperátorokSzáma(); i++)
  1161.             {
  1162.                 // Új gyermek csúcsot készítek.
  1163.                 Csúcs újCsúcs = new Csúcs(this);
  1164.                 // Kiprobálom az i.dik alapoperátort. Alkalmazható?
  1165.                 if (újCsúcs.SzuperOperátor(i))
  1166.                 {
  1167.                     // Ha igen, hozzáadom az újakhoz.
  1168.                     újCsúcsok.Add(újCsúcs);
  1169.                 }
  1170.             }
  1171.             return újCsúcsok;
  1172.         }
  1173.     }
  1174.  
  1175.     //8.6.1
  1176.     /// <summary>
  1177.     /// Minden gráfkereső algoritmus őse.
  1178.     /// A gráfkeresőknek csak a Keresés metódust kell megvalósítaniuk.
  1179.     /// Ez visszaad egy terminális csúcsot, ha talált megoldást, egyébként null értékkel tér vissza.
  1180.     /// A terminális csúcsból a szülő referenciákon felfelé haladva áll elő a megoldás.
  1181.     /// </summary>
  1182.     abstract class GráfKereső
  1183.     {
  1184.         private Csúcs startCsúcs; // A start csúcs csúcs.
  1185.                                   // Minden gráfkereső a start csúcsból kezd el keresni.
  1186.         public GráfKereső(Csúcs startCsúcs)
  1187.         {
  1188.             this.startCsúcs = startCsúcs;
  1189.         }
  1190.         // Jobb, ha a start csúcs privát, de a gyermek osztályok lekérhetik.
  1191.         protected Csúcs GetStartCsúcs() { return startCsúcs; }
  1192.         /// Ha van megoldás, azaz van olyan út az állapottér gráfban,
  1193.         /// ami a start csúcsból egy terminális csúcsba vezet,
  1194.         /// akkor visszaad egy megoldást, egyébként null.
  1195.         /// A megoldást egy terminális csúcsként adja vissza.
  1196.         /// Ezen csúcs szülő referenciáin felfelé haladva adódik a megoldás fordított sorrendben.
  1197.         public abstract Csúcs Keresés();
  1198.         /// <summary>
  1199.         /// Kiíratja a megoldást egy terminális csúcs alapján.
  1200.         /// Feltételezi, hogy a terminális csúcs szülő referenciáján felfelé haladva eljutunk a start csúcshoz.
  1201.         /// A csúcsok sorrendjét megfordítja, hogy helyesen tudja kiírni a megoldást.
  1202.         /// Ha a csúcs null, akkor kiírja, hogy nincs megoldás.
  1203.         /// </summary>
  1204.         /// <param name="egyTerminálisCsúcs">
  1205.         /// A megoldást képviselő terminális csúcs vagy null.
  1206.         /// </param>
  1207.         public void megoldásKiírása(Csúcs egyTerminálisCsúcs)
  1208.         {
  1209.             if (egyTerminálisCsúcs == null)
  1210.             {
  1211.                 Console.WriteLine("Nincs megoldás");
  1212.                 return;
  1213.             }
  1214.             // Meg kell fordítani a csúcsok sorrendjét.
  1215.             Stack<Csúcs> megoldás = new Stack<Csúcs>();
  1216.             Csúcs aktCsúcs = egyTerminálisCsúcs;
  1217.             while (aktCsúcs != null)
  1218.             {
  1219.                 megoldás.Push(aktCsúcs);
  1220.                 aktCsúcs = aktCsúcs.GetSzülő();
  1221.             }
  1222.             // Megfordítottuk, lehet kiírni.
  1223.             foreach (Csúcs akt in megoldás) Console.WriteLine(akt);
  1224.         }
  1225.     }
  1226.  
  1227.     //8.7.1
  1228.     /// <summary>
  1229.     /// A backtrack gráfkereső algoritmust megvalósító osztály.
  1230.     /// A három alap backtrack algoritmust egyben tartalmazza. Ezek
  1231.     /// - az alap backtrack
  1232.     /// - mélységi korlátos backtrack
  1233.     /// - emlékezetes backtrack
  1234.     /// Az ág-korlátos backtrack nincs megvalósítva.
  1235.     /// </summary>
  1236.     class BackTrack : GráfKereső
  1237.     {
  1238.         int korlát; // Ha nem nulla, akkor mélységi korlátos kereső.
  1239.         bool emlékezetes; // Ha igaz, emlékezetes kereső.
  1240.         public BackTrack(Csúcs startCsúcs, int korlát, bool emlékezetes) : base(startCsúcs)
  1241.         {
  1242.             this.korlát = korlát;
  1243.             this.emlékezetes = emlékezetes;
  1244.         }
  1245.         // nincs mélységi korlát, se emlékezet
  1246.         public BackTrack(Csúcs startCsúcs) : this(startCsúcs, 0, false) { }
  1247.         // mélységi korlátos kereső
  1248.         public BackTrack(Csúcs startCsúcs, int korlát) : this(startCsúcs, korlát, false) { }
  1249.         // emlékezetes kereső
  1250.         public BackTrack(Csúcs startCsúcs, bool emlékezetes) : this(startCsúcs, 0, emlékezetes) { }
  1251.         // A keresés a start csúcsból indul.
  1252.         // Egy terminális csúcsot ad vissza. A start csúcsból el lehet jutni ebbe a terminális csúcsba.
  1253.         // Ha nincs ilyen, akkor null értéket ad vissza.
  1254.         public override Csúcs Keresés() { return Keresés(GetStartCsúcs()); }
  1255.         // A kereső algoritmus rekurzív megvalósítása.
  1256.         // Mivel rekurzív, ezért a visszalépésnek a "return null" felel meg.
  1257.         private Csúcs Keresés(Csúcs aktCsúcs)
  1258.         {
  1259.             int mélység = aktCsúcs.GetMélység();
  1260.             // mélységi korlát vizsgálata
  1261.             if (korlát > 0 && mélység >= korlát) return null;
  1262.             // emlékezet használata kör kiszűréséhez
  1263.             Csúcs aktSzülő = null;
  1264.             if (emlékezetes) aktSzülő = aktCsúcs.GetSzülő();
  1265.             while (aktSzülő != null)
  1266.             {
  1267.                 // Ellenőrzöm, hogy jártam-e ebben az állapotban. Ha igen, akkor visszalépés.
  1268.                 if (aktCsúcs.Equals(aktSzülő)) return null;
  1269.                 // Visszafelé haladás a szülői láncon.
  1270.                 aktSzülő = aktSzülő.GetSzülő();
  1271.             }
  1272.             if (aktCsúcs.TerminálisCsúcsE())
  1273.             {
  1274.                 // Megvan a megoldás, vissza kell adni a terminális csúcsot.
  1275.                 return aktCsúcs;
  1276.             }
  1277.             // Itt hívogatom az alapoperátorokat a szuper operátoron
  1278.             // keresztül. Ha valamelyik alkalmazható, akkor új csúcsot
  1279.             // készítek, és meghívom önmagamat rekurzívan.
  1280.             for (int i = 0; i < aktCsúcs.OperátorokSzáma(); i++)
  1281.             {
  1282.                 // Elkészítem az új gyermek csúcsot.
  1283.                 // Ez csak akkor lesz kész, ha alkalmazok rá egy alkalmazható operátort is.
  1284.                 Csúcs újCsúcs = new Csúcs(aktCsúcs);
  1285.                 // Kipróbálom az i.dik alapoperátort. Alkalmazható?
  1286.                 if (újCsúcs.SzuperOperátor(i))
  1287.                 {
  1288.                     // Ha igen, rekurzívan meghívni önmagam az új csúcsra.
  1289.                     // Ha nem null értéket ad vissza, akkor megvan a megoldás.
  1290.                     // Ha null értéket, akkor ki kell próbálni a következő alapoperátort.
  1291.                     Csúcs terminális = Keresés(újCsúcs);
  1292.                     if (terminális != null)
  1293.                     {
  1294.                         // Visszaadom a megoldást képviselő terminális csúcsot.
  1295.                         return terminális;
  1296.                     }
  1297.                     // Az else ágon kellene visszavonni az operátort.
  1298.                     // Erre akkor van szükség, ha az új gyermeket létrehozásában nem lenne klónozást.
  1299.                     // Mivel klónoztam, ezért ez a rész üres.
  1300.                 }
  1301.             }
  1302.             // Ha kipróbáltam az összes operátort és egyik se vezetett megoldásra, akkor visszalépés.
  1303.             // A visszalépés hatására eggyel feljebb a következő alapoperátor kerül sorra.
  1304.             return null;
  1305.         }
  1306.     }
  1307.  
  1308.     //8.9.1
  1309.     class Program
  1310.     {
  1311.         static void Main(string[] args)
  1312.         {
  1313.             Csúcs startCsúcs;
  1314.             GráfKereső kereső;
  1315.  
  1316.             Console.WriteLine("A 3 szerzetes 3 kanibál problémát oldjuk meg.");
  1317.             startCsúcs = new Csúcs(new SzerzetesekÉsKannibálokÁllapot(3, 3));
  1318.             Console.WriteLine("A kereső egy 15 mélységi korlátos és emlékezetes backtrack.");
  1319.             kereső = new BackTrack(startCsúcs, 15, true);
  1320.             kereső.megoldásKiírása(kereső.Keresés());
  1321.  
  1322.             Console.WriteLine("A Die Hard problémát oldjuk meg.");
  1323.             startCsúcs = new Csúcs(new DieHardProbléma());
  1324.             Console.WriteLine("A kereső egy 15 mélységi korlátos és emlékezetes backtrack.");
  1325.             kereső = new BackTrack(startCsúcs, 15, true);
  1326.             kereső.megoldásKiírása(kereső.Keresés());
  1327.  
  1328.             Console.WriteLine("A gyümölcsös problémát oldjuk meg.");
  1329.             startCsúcs = new Csúcs(new Feladat2p5());
  1330.             Console.WriteLine("A kereső egy 15 mélységi korlátos és emlékezetes backtrack.");
  1331.             kereső = new BackTrack(startCsúcs, 15, true);
  1332.             kereső.megoldásKiírása(kereső.Keresés());
  1333.  
  1334.             Console.WriteLine("A forgatós problémát oldjuk meg.");
  1335.             startCsúcs = new Csúcs(new Feladat2p8());
  1336.             Console.WriteLine("A kereső egy 15 mélységi korlátos és emlékezetes backtrack.");
  1337.             kereső = new BackTrack(startCsúcs, 15, true);
  1338.             kereső.megoldásKiírása(kereső.Keresés());
  1339.  
  1340.             Console.WriteLine("A Feladat 1.3 problémát oldjuk meg.");
  1341.             startCsúcs = new Csúcs(new Feladat_1_3());
  1342.             Console.WriteLine("A kereső egy 15 mélységi korlátos és emlékezetes backtrack.");
  1343.             kereső = new BackTrack(startCsúcs, 15, true);
  1344.             kereső.megoldásKiírása(kereső.Keresés());
  1345.  
  1346.             Console.WriteLine("A Feladat 2.38 problémát oldjuk meg.");
  1347.             startCsúcs = new Csúcs(new Feladat_2_38());
  1348.             Console.WriteLine("A kereső egy 25 mélységi korlátos és emlékezetes backtrack.");
  1349.             kereső = new BackTrack(startCsúcs, 30, true);
  1350.             kereső.megoldásKiírása(kereső.Keresés());
  1351.  
  1352.  
  1353.             Console.ReadLine();
  1354.         }
  1355.     }
  1356. }
Tags: feladat
Advertisement
Add Comment
Please, Sign In to add comment