দাবা খেলার জন্য অবজেক্ট ওরিয়েন্টড ডিজাইন [বন্ধ]


88

আমি কীভাবে একটি অবজেক্ট ওরিয়েন্টেড পদ্ধতিতে ডিজাইন করতে এবং ভাবতে পারি তার অনুভূতি পাওয়ার চেষ্টা করছি এবং এই বিষয়ে সম্প্রদায়ের কাছ থেকে কিছু প্রতিক্রিয়া পেতে চাই। নিম্নলিখিত কোনও দাবা খেলার একটি উদাহরণ যা আমি ওও পদ্ধতিতে ডিজাইন করতে চাই। এটি একটি খুব বিস্তৃত নকশা এবং এই পর্যায়ে আমার ফোকাসটি কী বার্তাগুলি এবং কীভাবে অবজেক্টগুলি একে অপরের সাথে গেম অনুকরণের জন্য যোগাযোগ করে তার জন্য দায়বদ্ধ তা সনাক্ত করা responsible খারাপ ডিজাইনের উপাদান (উচ্চ সংযুক্তি, খারাপ সংহতি ইত্যাদি) এবং সেগুলিতে কীভাবে উন্নতি করা যায় সেগুলি দয়া করে চিহ্নিত করুন।

দাবা খেলা নিম্নলিখিত ক্লাসে আছে

  • বোর্ড
  • প্লেয়ার
  • টুকরা
  • স্কয়ার
  • দাবা খেলা

বোর্ডটি স্কোয়ারগুলি নিয়ে গঠিত এবং তাই স্কয়ার অবজেক্টগুলি তৈরি এবং পরিচালনার জন্য বোর্ডকে দায়বদ্ধ করা যায়। প্রতিটি টুকরাও একটি বর্গক্ষেত্রের হয় তাই প্রতিটি টুকরাতে এটি বর্গক্ষেত্রের একটি রেফারেন্স থাকে। (এটা কোনো কিছু হলো?). তারপরে প্রতিটি টুকরা নিজেকে এক বর্গ থেকে অন্য স্কোয়ারে স্থানান্তর করতে দায়ী। খেলোয়াড় শ্রেণি তার নিজের মালিকানাধীন সমস্ত টুকরাগুলির রেফারেন্স রাখে এবং তাদের তৈরির জন্যও দায়ী (প্লেয়ারকে পিস তৈরি করা উচিত?)। খেলোয়াড়ের একটি পদ্ধতি টু টুর রয়েছে যার ফলস্বরূপ একটি মেথড মুভিপিস কল করে যা টুকরো শ্রেণীর অন্তর্গত যা টুকরোটির বর্তমান অবস্থান থেকে অন্য অবস্থানে পরিবর্তন করে changes বোর্ড ক্লাসের জন্য অবশ্যই কী দায়বদ্ধ হতে হবে তা নিয়ে আমি এখন বিভ্রান্ত হয়ে পড়েছি। আমি ধরে নিয়েছিলাম যে গেমের বর্তমান অবস্থা নির্ধারণ এবং গেমটি কখন শেষ হয়েছে তা জানতে এটি দরকার ছিল। কিন্তু যখন একটি টুকরা এটি পরিবর্তন করে ' এর অবস্থান কীভাবে বোর্ড আপডেট হওয়া উচিত? এটি কি স্কোয়ারের একটি পৃথক অ্যারে বজায় রাখতে হবে যার উপর টুকরো রয়েছে এবং টুকরা সরানোর সাথে সাথে এটি আপডেট হয়?

এছাড়াও, দাবাগেমটি অন্তত বোর্ড এবং প্লেয়ার অবজেক্ট তৈরি করে যারা যথাক্রমে স্কোয়ার এবং টুকরা তৈরি করে এবং সিমুলেশন শুরু করে। সংক্ষিপ্তভাবে, দাবাগেমের কোডটির মতো দেখতে এটি হতে পারে

Player p1 =new Player();
Player p2 = new Player();

Board b = new Board();

while(b.isGameOver())
{
  p1.takeTurn(); // calls movePiece on the Piece object
  p2.takeTurn();

}

বোর্ডের অবস্থা কীভাবে আপডেট হবে সে সম্পর্কে আমি অস্পষ্ট। টুকরা বোর্ডে একটি রেফারেন্স থাকা উচিত? দায় কোথায় থাকা উচিত? কে রেফারেন্স রাখে? আপনার ইনপুটগুলিতে আমাকে সহায়তা করুন এবং এই নকশায় সমস্যাগুলি দেখান। আমি ডিজাইনের দিকটিতে কেবল আগ্রহী হওয়ায় আমি ইচ্ছাকৃতভাবে কোনও অ্যালগরিদম বা গেম খেলার আরও বিশদগুলিতে মনোযোগ দিচ্ছি না। আমি আশা করি এই সম্প্রদায়টি মূল্যবান অন্তর্দৃষ্টি সরবরাহ করতে পারে।


4
নিতপিকি মন্তব্য: পি 1 takeTurn()এর পদক্ষেপটি খেলাটি শেষ হলে পি 2 কল করা উচিত নয় । কম নীটপিকি মন্তব্য: আমি খেলোয়াড়দের কল করা আরও স্বাভাবিক মনে করি whiteএবং black
ক্রিস্টোফার জনসন

রাজি। তবে আমি যেমন বলেছিলাম, আমি নকশাগুলির দিকগুলিতে এবং কী কী পদক্ষেপের জন্য কোন বিষয়বস্তুদের দায়বদ্ধ হওয়া উচিত এবং কী রেফারেন্স রাখে তাতে আরও আগ্রহী।
সিড

আপনার স্নিপেটে উপরে বর্ণিত মতটি আমি পছন্দ করেছি। আমার বাস্তবায়নে, প্রতিটি টুকরোটির সম্পূর্ণ অবস্থানের অভ্যন্তরীণ অনুলিপি রয়েছে কারণ এটি এটি নিজস্ব canMove()ফাংশনে ব্যবহার করবে । এবং সরানো হয়ে গেলে, অন্যান্য সমস্ত টুকরা বোর্ডের নিজস্ব অভ্যন্তরীণ অনুলিপি আপডেট করে। আমি জানি এটি সর্বোত্তম নয়, তবে সেই সময়টি সি ++ শিখতে আকর্ষণীয় ছিল। পরে, একজন দাবা খেলোয়াড়ের বন্ধু আমাকে বলেছিল যে সে classesপ্রতিটি টুকরোটির পরিবর্তে প্রতিটি স্কোয়ারের জন্য থাকবে । এবং সেই মন্তব্যটি আমাকে খুব আকর্ষণীয় বলে মন্তব্য করেছিল।
ইগেনফিল্ড

উত্তর:


54

আমি আসলে ঠিক একটি দাবা বোর্ড, টুকরা, বিধি, ইত্যাদি একটি পূর্ণ C # এর বাস্তবায়ন লিখেছিলেন এখানে মোটামুটিভাবে কত আমি তা অনুকরণে (মুছে প্রকৃত বাস্তবায়ন যেহেতু আমি নিতে চাই না সব মজা আপনার কোডিং এর বাইরে):

public enum PieceType {
    None, Pawn, Knight, Bishop, Rook, Queen, King
}

public enum PieceColor {
    White, Black
}

public struct Piece {
    public PieceType Type { get; set; }
    public PieceColor Color { get; set; }
}

public struct Square {
    public int X { get; set; }
    public int Y { get; set; }

    public static implicit operator Square(string str) {
        // Parses strings like "a1" so you can write "a1" in code instead
        // of new Square(0, 0)
    }
}

public class Board {
    private Piece[,] board;

    public Piece this[Square square] { get; set; }

    public Board Clone() { ... }
}

public class Move {
    public Square From { get; }
    public Square To { get; }
    public Piece PieceMoved { get; }
    public Piece PieceCaptured { get; }
    public PieceType Promotion { get; }
    public string AlgebraicNotation { get; }
}

public class Game {
    public Board Board { get; }
    public IList<Move> Movelist { get; }
    public PieceType Turn { get; set; }
    public Square? DoublePawnPush { get; set; } // Used for tracking valid en passant captures
    public int Halfmoves { get; set; }

    public bool CanWhiteCastleA { get; set; }
    public bool CanWhiteCastleH { get; set; }
    public bool CanBlackCastleA { get; set; }
    public bool CanBlackCastleH { get; set; }
}

public interface IGameRules {
    // ....
}

মূল ধারণাটি হ'ল গেম / বোর্ড / ইত্যাদি কেবল গেমের অবস্থা সঞ্চয় করে। আপনি এগুলি চাইলে উদাহরণস্বরূপ একটি অবস্থান সেট আপ করতে পারেন। আমার একটি ক্লাস রয়েছে যা আমার আইগামারুলস ইন্টারফেস প্রয়োগ করে যা এর জন্য দায়ী:

  • কাস্টিং এবং এন পাসেন্ট সহ কী পদক্ষেপগুলি বৈধ তা নির্ধারণ করা।
  • নির্দিষ্ট পদক্ষেপ বৈধ কিনা তা নির্ধারণ করা হচ্ছে।
  • খেলোয়াড়রা চেক / চেকমেট / অচলাবস্থায় থাকা অবস্থায় নির্ধারণ করা হচ্ছে।
  • চালনা চালানো হচ্ছে।

গেম / বোর্ডের ক্লাস থেকে বিধি বিচ্ছিন্ন করার অর্থ আপনি তুলনামূলকভাবে সহজেই রূপগুলি প্রয়োগ করতে পারবেন। নিয়ম ইন্টারফেসের সমস্ত পদ্ধতিতে Gameকোনও পদক্ষেপ গ্রহণ করা হয় যা কোন পদক্ষেপগুলি বৈধ তা নির্ধারণ করার জন্য তারা পরিদর্শন করতে পারে।

মনে রাখবেন যে আমি প্লেয়ারের তথ্য সংরক্ষণ করি না Game। আমার একটি পৃথক শ্রেণি রয়েছে Tableযা গেমের মেটাডেটা সংরক্ষণ করার জন্য দায়বদ্ধ যেমন কে খেলছিল, কখন খেলা হয়েছিল ইত্যাদি etc.

সম্পাদনা: নোট করুন যে এই উত্তরের উদ্দেশ্যটি আপনাকে পূরণ করতে পারে এমন টেম্পলেট কোডটি দেয় না - আমার কোডটিতে প্রতিটি আইটেমটিতে আরও কিছু তথ্য সঞ্চিত থাকে, আরও পদ্ধতি ইত্যাদি The লক্ষ্য আপনি অর্জন করার চেষ্টা করছেন


4
বিস্তারিত উত্তরের জন্য আপনাকে ধন্যবাদ। যাইহোক, নকশা সংক্রান্ত আমার কয়েকটি প্রশ্ন রয়েছে। উদাহরণস্বরূপ, সরানো কেন শ্রেণি হওয়া উচিত তা তাত্ক্ষণিকভাবে স্পষ্ট নয়। আমার একমাত্র ফোকাস দায়িত্ব নির্ধারণ এবং ক্লাসের মধ্যে মিথস্ক্রিয়াগুলি সবচেয়ে পরিষ্কার পদ্ধতিতে সিদ্ধান্ত নেওয়া। আমি কোনও ডিজাইনের সিদ্ধান্তের পিছনে "কেন" জানতে চাই। আপনি যে নকশার সিদ্ধান্ত নিয়েছিলেন সেগুলিতে আপনি কীভাবে পৌঁছেছিলেন এবং কেন সেগুলি ভাল পছন্দ সে সম্পর্কে আমি স্পষ্ট নই।
সিড

Moveএমন একটি শ্রেণি যাতে আপনি
মুভি তালিকায় পুরো মুভের ইতিহাস সংরক্ষণ

@ সিডিউইউই কি Gameকোনও বাস্তবায়নকারীকে ডেলগেট করছে IGameRulesবা আপনি কোনও কিছুর বাইরে নিয়মের প্রয়োগ করছেন? পরেরটিটি অনুপযুক্ত বলে মনে হচ্ছে যেহেতু গেমটি তার নিজস্ব রাজ্যটি রক্ষা করতে পারে না?
প্ল্লেক্স

4
এটি নির্বোধ হতে পারে তবে গেমের ক্লাসটি পিসটাইপের পরিবর্তে পাইসক্লোর টাইপের হওয়া উচিত নয়?
ডেনিস ভ্যান গিলস

4
@ নিখিল তারা উভয় খেলোয়াড় এখনও কোন দিকে ক্যাসল করতে পারে তা নির্দেশ করে (এ এবং এইচ ফাইলের দিকে)। এই মানগুলি সত্য থেকে শুরু হয়। যদি হোয়াইট এর এ রুক মুভ করে, CanWhiteCastleA কে মিথ্যা বানানো হয়, এবং তেমনিভাবে H রুকের জন্যও। যদি সাদা রাজা চলে যায় তবে উভয়কেই মিথ্যা বানানো হবে। এবং কালো জন্য একই প্রক্রিয়া।
সিডিওউই

6

মোটামুটি বেসিক দাবা খেলার জন্য আমার ধারণাটি এখানে:

class GameBoard {
 IPiece config[8][8];  

 init {
  createAndPlacePieces("Black");
  createAndPlacePieces("White");
  setTurn("Black");

 }

 createAndPlacePieces(color) {
   //generate pieces using a factory method
   //for e.g. config[1][0] = PieceFactory("Pawn",color);
 }

 setTurn(color) {
   turn = color;
 }

 move(fromPt,toPt) {
  if(getPcAt(fromPt).color == turn) {
    toPtHasOppositeColorPiece = getPcAt(toPt) != null && getPcAt(toPt).color != turn;
    possiblePath = getPcAt(fromPt).generatePossiblePath(fromPt,toPt,toPtHasOppositeColorPiece);
   if(possiblePath != NULL) {
      traversePath();
      changeTurn();
   }
  }
 } 

}

Interface IPiece {
  function generatePossiblePath(fromPt,toPt,toPtHasEnemy);
}

class PawnPiece implements IPiece{
  function generatePossiblePath(fromPt,toPt,toPtHasEnemy) {
    return an array of points if such a path is possible
    else return null;
  }
}

class ElephantPiece implements IPiece {....}

0

আমি সম্প্রতি পিএইচপি-তে একটি দাবা প্রোগ্রাম তৈরি করেছি ( ওয়েবসাইট এখানে ক্লিক করুন , উত্স ক্লিক করুন ) এবং আমি এটিকে উদ্দেশ্যমুখী করে তুলেছি। আমি ব্যবহৃত ক্লাসগুলি এখানে।

  • চেসরুলবুক (স্ট্যাটিক) - আমি আমার সমস্ত generate_legal_moves()কোড এখানে রেখেছি । এই পদ্ধতিতে একটি বোর্ড দেওয়া হয়, যার পালা এটি হয় এবং আউটপুটের বিশদের স্তরটি নির্ধারণ করার জন্য কিছু পরিবর্তনশীল এবং এটি সেই অবস্থানের জন্য সমস্ত আইনী পদক্ষেপ উত্পন্ন করে। এটি চেসমভের একটি তালিকা প্রদান করে।
  • চেসমভ - বর্গক্ষেত্রের সূচনা, সমাপ্তি বর্গক্ষেত্র, রঙ, টুকরো টাইপ, ক্যাপচার, চেক, চেকমেট, প্রচারের টুকরো টাইপ এবং এন পাসেন্ট সহ বীজগণিত স্বরলিপি তৈরির জন্য প্রয়োজনীয় সমস্ত কিছু সঞ্চয় করে । Additionalচ্ছিক অতিরিক্ত ভেরিয়েবলগুলির মধ্যে ছিন্নমূলকরণ (Rae4 এর মতো চলার জন্য), কাস্টলিং এবং বোর্ড অন্তর্ভুক্ত রয়েছে।
  • চেসবোর্ড - একটি দাবা ফেইন হিসাবে একই তথ্য সংরক্ষণ করে, একটি 8x8 অ্যারে সহ স্কোয়ারগুলি উপস্থাপন করে এবং দাবাপিসগুলি সংরক্ষণ করে, যার পালা এটি টার্গেট বর্গক্ষেত্র, কাস্টলিং রাইটস, হাফমোভ ক্লক এবং ফুলমোভ ক্লক।
  • দাবাপিস - স্টোরের টুকরো টাইপ, রঙ, বর্গক্ষেত্র এবং টুকরা মান (উদাহরণস্বরূপ, প্যাড = 1, নাইট = 3, রোক = 5, ইত্যাদি)
  • দাবা স্কয়ার - র‌্যাঙ্ক এবং ফাইল সংরক্ষণ করে ints

আমি বর্তমানে এই কোডটি দাবা এআইতে পরিণত করার চেষ্টা করছি, সুতরাং এটি দ্রুত হওয়া দরকার। আমি generate_legal_moves()ফাংশনটি 1500 মিমি থেকে 8 এমএসে অনুকূলিত করেছি এবং এখনও এটিতে কাজ করছি working আমি যে পাঠগুলি শিখেছি তা হ'ল ...

  • ডিফল্টরূপে প্রতিটি চেসমুভে একটি সম্পূর্ণ দাবাবোর্ড সংরক্ষণ করবেন না। প্রয়োজনে কেবল বোর্ডটিকে মুভ এ সংরক্ষণ করুন।
  • intসম্ভব হলে আদিম ধরণের ব্যবহার করুন । এ কারণেই মানব পাঠযোগ্য দাবা স্কোয়ার নোটেশন যেমন "এ 4" এর সাথে একটি বর্ণমালা সংরক্ষণ করার পরিবর্তে ChessSquareর‌্যাঙ্ক এবং ফাইল intসংরক্ষণ করে filestring
  • প্রোগ্রামটি মুভি ট্রিটিতে অনুসন্ধানের সময় কয়েক হাজার চিজস্কয়ার তৈরি করে। আমি সম্ভবত প্রোগ্রামটি চেসস্কয়ারগুলি ব্যবহার না করার জন্য রিফ্যাক্টর করব, যা গতি বাড়িয়ে তুলবে।
  • আপনার ক্লাসে কোনও অপ্রয়োজনীয় ভেরিয়েবল গণনা করবেন না। মূলত, আমার প্রতিটি চেসবোর্ডে FEN গণনা করা সত্যিই প্রোগ্রামটির গতিটি হারাচ্ছিল। আমাকে এটি একটি প্রোফাইলারের সাথে খুঁজে বের করতে হয়েছিল ।

আমি জানি এটি পুরানো, তবে আশা করি এটি কারও সাহায্য করবে। শুভকামনা!

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.