উত্তর:
আমি একটি সমাধান নিয়ে এসেছি যা সম্ভবত সবচেয়ে দক্ষ নয়, তবে এটি যথেষ্ট ভালভাবে কাজ করে। মূলত:
এটি একটি কাজ করে, তবে প্রায়শই বেশ দুর্বল ক্রসওয়ার্ড করে। উন্নততর ফলাফল নিয়ে আসার জন্য আমি বেসিক রেসিপিটিতে বেশ কয়েকটি পরিবর্তন করেছি।
আমি সম্প্রতি পাইথনে নিজের লেখা লিখেছি। আপনি এটি এখানে খুঁজে পেতে পারেন: http://bryanhelmig.com/python-crossword-puzzle-generator/ । এটি ঘন এনওয়াইটি স্টাইলের ক্রসওয়ার্ড তৈরি করে না, তবে ক্রসওয়ার্ডগুলির স্টাইলটি আপনি কোনও সন্তানের ধাঁধা বইতে খুঁজে পেতে পারেন।
কয়েকটি অ্যালগরিদমের বিপরীতে আমি সেখানে জানতে পেরেছি যে কয়েকজনের মতো শব্দ রাখার একটি র্যান্ডম ব্রুট-ফোর্স পদ্ধতি বাস্তবায়িত হয়েছিল, আমি শব্দ স্থানটিতে সামান্য বুদ্ধিমান ব্রুট-ফোর্স পদ্ধতির প্রয়োগ করার চেষ্টা করেছি। আমার প্রক্রিয়াটি এখানে:
শেষ পর্যন্ত, আপনার কাছে একটি শালীন ক্রসওয়ার্ড ধাঁধা বা শব্দ অনুসন্ধান ধাঁধা রয়েছে, কারণ তারা প্রায় একই রকম they এটি বরং ভাল চালানোর ঝোঁক, তবে আপনার উন্নতির বিষয়ে কোনও পরামর্শ থাকলে তা আমাকে জানান। বড় গ্রিডগুলি তাত্পর্যপূর্ণভাবে ধীর গতিতে চলে; বড় শব্দের রৈখিকভাবে তালিকাবদ্ধ করে। আরও বড় শব্দ তালিকার আরও ভাল শব্দ স্থান নির্ধারণের সংখ্যায় অনেক বেশি সুযোগ রয়েছে।
array.sort(key=f)
স্থিতিশীল, যার অর্থ (উদাহরণস্বরূপ) যে দৈর্ঘ্য অনুসারে একটি বর্ণানুক্রমিক শব্দ তালিকাকে বাছাই করা 8-অক্ষরের শব্দগুলিকে বর্ণমালা অনুসারে বাছাই করে রাখবে।
আমি আসলে প্রায় দশ বছর আগে একটি ক্রসওয়ার্ড জেনারেশন প্রোগ্রাম লিখেছিলাম (এটি গুপ্ত ছিল তবে একই নিয়মগুলি সাধারণ ক্রসওয়ার্ডের জন্য প্রযোজ্য)।
এটিতে ব্যবহারের তারিখ অবতরণ করে বাছাই করা একটি ফাইলে শব্দের তালিকা (এবং সম্পর্কিত সংকেত) রয়েছে (যাতে কম ব্যবহৃত শব্দগুলি ফাইলের শীর্ষে থাকে)। একটি টেম্পলেট, মূলত একটি কালো এবং মুক্ত স্কোয়ার প্রতিনিধিত্বকারী একটি বিট মাস্ক, ক্লায়েন্ট দ্বারা সরবরাহ করা একটি পুল থেকে এলোমেলোভাবে বেছে নেওয়া হয়েছিল।
তারপরে ধাঁধার প্রতিটি অপূর্ণ-শব্দের জন্য (মূলত প্রথম ফাঁকা বর্গক্ষেত্রটি সন্ধান করুন এবং দেখুন যে ডানদিকে একটি (পুরো শব্দটি) অথবা নীচের একটিটিও ফাঁকা রয়েছে) এর জন্য অনুসন্ধান করা হয়েছিল এই শব্দটির মধ্যে ইতিমধ্যে অক্ষরগুলি বিবেচনা করে, ফাইলটি উপযুক্ত প্রথম শব্দটির সন্ধান করছে। যদি উপযুক্ত শব্দ না আসে তবে আপনি পুরো শব্দটিকে অসম্পূর্ণ হিসাবে চিহ্নিত করেছেন এবং এগিয়ে গিয়েছেন।
শেষে কিছু অসম্পূর্ণ শব্দ থাকবে যা সংকলকটি পূরণ করতে হবে (এবং শব্দটি এবং চাইলে ফাইলটিতে একটি ক্লু যুক্ত করতে হবে)। যদি তারা কোনও ধারণাগুলি নিয়ে আসতে না পারে তবে সীমাবদ্ধতা পরিবর্তন করতে তারা ক্রসওয়ার্ডটি ম্যানুয়ালি সম্পাদনা করতে পারে বা কেবল মোট পুনরায় প্রজন্মের জন্য বলতে পারে।
একবার শব্দ / ক্লু ফাইলটি একটি নির্দিষ্ট আকারে উঠল (এবং এটি এই ক্লায়েন্টটির জন্য দিনে 50-100 টি ক্লু যুক্ত করা হয়েছিল), খুব কমই দু'বারের থেকে তিনটি ম্যানুয়াল ফিক্স আপের ঘটনা ঘটে যা প্রতিটি ক্রসওয়ার্ডের জন্য করতে হয়েছিল had ।
এই অ্যালগরিদম 60 সেকেন্ডে 50 ঘন 6x9 তীর ক্রসওয়ার্ড তৈরি করে । এটি একটি ওয়ার্ড ডাটাবেস (শব্দ + টিপস সহ) এবং একটি বোর্ড ডাটাবেস (প্রাক কনফিগার বোর্ড সহ) ব্যবহার করে।
1) Search for all starting cells (the ones with an arrow), store their size and directions
2) Loop through all starting cells
2.1) Search a word
2.1.1) Check if it was not already used
2.1.2) Check if it fits
2.2) Add the word to the board
3) Check if all cells were filled
একটি বড় শব্দের ডাটাবেস প্রজন্মের সময়কে যথেষ্ট হ্রাস করে এবং কিছু ধরণের বোর্ডগুলি পূরণ করা শক্ত hard বড় বোর্ডগুলিকে সঠিকভাবে পূরণ করতে আরও সময় প্রয়োজন!
উদাহরণ:
প্রাক-কনফিগার 6x9 বোর্ড:
(# মানে একটি ঘরে একটি টিপ,% এর অর্থ একটি কক্ষে দুটি টিপস, তীর দেখানো হয়নি)
# - # # - % # - #
- - - - - - - - -
# - - - - - # - -
% - - # - # - - -
% - - - - - % - -
- - - - - - - - -
6x9 বোর্ড উত্পন্ন:
# C # # P % # O #
S A T E L L I T E
# N I N E S # T A
% A B # A # G A S
% D E N S E % W E
C A T H E D R A L
টিপস [লাইন, কলাম]:
[1,0] SATELLITE: Used for weather forecast
[5,0] CATHEDRAL: The principal church of a city
[0,1] CANADA: Country on USA's northern border
[0,4] PLEASE: A polite way to ask things
[0,7] OTTAWA: Canada's capital
[1,2] TIBET: Dalai Lama's region
[1,8] EASEL: A tripod used to put a painting
[2,1] NINES: Dressed up to (?)
[4,1] DENSE: Thick; impenetrable
[3,6] GAS: Type of fuel
[1,5] LS: Lori Singer, american actress
[2,7] TA: Teaching assistant (abbr.)
[3,1] AB: A blood type
[4,3] NH: New Hampshire (abbr.)
[4,5] ED: (?) Harris, american actor
[4,7] WE: The first person of plural (Grammar)
যদিও এটি একটি পুরানো প্রশ্ন, আমি একইভাবে করা কাজের উপর ভিত্তি করে একটি উত্তর চেষ্টা করব।
সীমাবদ্ধতা সমস্যাগুলি সমাধান করার জন্য অনেকগুলি পন্থা রয়েছে (যা জেনারেলটি এনপিসি জটিলতার শ্রেণিতে থাকে)।
এটি সম্মিলিত অপ্টিমাইজেশন এবং সীমাবদ্ধ প্রোগ্রামিং সম্পর্কিত। এক্ষেত্রে সীমাবদ্ধতা হ'ল গ্রিডের জ্যামিতি এবং শব্দের অনন্যতা ইত্যাদির প্রয়োজনীয়তা ..
র্যান্ডমাইজেশন / আনিলিং পদ্ধতিগুলিও কাজ করতে পারে (যদিও সঠিক সেটিংয়ের মধ্যে))
দক্ষ সরলতা কেবল চূড়ান্ত জ্ঞান হতে পারে!
প্রয়োজনীয়তাগুলি কম-বেশি সম্পূর্ণ ক্রসওয়ার্ড সংকলক এবং (ভিজ্যুয়াল ডাব্লুওয়াইএসআইওয়াইওয়াইজি) নির্মাতার জন্য ছিল।
ডাব্লুওয়াইএসআইওয়াইওয়াইজি বিল্ডার অংশটি বাদ দিয়ে সংকলকের রূপরেখাটি হ'ল:
উপলভ্য ওয়ার্ডলিস্টগুলি লোড করুন (শব্দের দৈর্ঘ্য অনুসারে বাছাই করা, অর্থাৎ ২,৩, .., ২০)
ব্যবহারকারীর দ্বারা নির্মিত গ্রিডে ওয়ার্ডস্লটস (অর্থাত্ গ্রিড শব্দ) সন্ধান করুন (উদাহরণস্বরূপ x, y দৈর্ঘ্যের এল, অনুভূমিক বা উল্লম্ব সহ) (জটিলতা O (N))
গ্রিড শব্দের ছেদযুক্ত বিন্দুগুলি গণনা করুন (যেটি পূরণ করা দরকার) (জটিলতা হে (এন ^ 2))
বর্ণমালার শব্দের ছেদগুলিকে বর্ণমালার বিভিন্ন অক্ষরের সাথে গণনা করুন (এটি টেমপ্লেট ব্যবহার করে শব্দের সাথে মিলের সন্ধান করতে দেয় যেমন সিডব্লিউসি দ্বারা ব্যবহৃত সিক কম্বন থিসিস ) (জটিলতা ও (ডাব্লুএল * আল))
পদক্ষেপ .3 এবং .4 এই কাজটি করার অনুমতি দেয়:
ক। নিজের সাথে গ্রিড শব্দের ছেদগুলি এই গ্রিড শব্দের জন্য উপলভ্য শব্দের সাথে সম্পর্কিত শব্দ তালিকার মিল খুঁজে পাওয়ার চেষ্টা করার জন্য একটি "টেম্পলেট" তৈরি করতে সক্ষম করে (ইতিমধ্যে একটি নির্দিষ্ট শর্তে পূর্ণ হওয়া এই শব্দের সাথে অন্য ছেদযুক্ত শব্দের অক্ষর ব্যবহার করে) অ্যালগরিদমের পদক্ষেপ)
খ। বর্ণমালার সাথে একটি শব্দ তালিকার শব্দের ছেদগুলি কোনও প্রদত্ত "টেমপ্লেট" (যেমন 1 ম স্থানে 'এ' এবং তৃতীয় স্থানে 'বি' ইত্যাদি মিলে যায়) (মিলিয়ে প্রার্থী) শব্দগুলি খুঁজে পেতে সক্ষম করে)
সুতরাং এই ডেটা স্ট্রাকচার প্রয়োগের সাথে ব্যবহৃত অ্যালগরিদমটি এরকম ছিল:
দ্রষ্টব্য: গ্রিড এবং শব্দের ডাটাবেস স্থির থাকলে পূর্ববর্তী পদক্ষেপগুলি একবারে একবার করা যেতে পারে।
অ্যালগরিদমের প্রথম পদক্ষেপটি এলোমেলোভাবে একটি ফাঁকা ওয়ার্ল্ডস্লট (গ্রিড শব্দ) নির্বাচন করুন এবং এর সাথে যুক্ত ওয়ার্ডলিস্ট থেকে প্রার্থী শব্দটি পূরণ করুন (এলোমোরিয়ামের ক্রমাগত মৃত্যুদণ্ড কার্যকর করতে বিভিন্ন দ্রাবক উত্পাদন করতে সক্ষম) (জটিলতা ও (1) বা ও ( এন))
প্রতিটি খালি শব্দের স্লটের জন্য (যেগুলি ইতিমধ্যে ভরা ওয়ার্ডস্লট সহ ছেদগুলি রয়েছে), একটি সীমাবদ্ধতার অনুপাত গণনা করুন (এটি পরিবর্তিত হতে পারে, সহজ পদক্ষেপটি সেই ধাপে উপলব্ধ সমাধানের সংখ্যা) এবং এই অনুপাত দ্বারা ফাঁকা ওয়ার্ডস্লটগুলি বাছাই করুন (জটিলতা হে (এনলগএন) ) বা ও (এন))
পূর্ববর্তী পদক্ষেপে গণনা করা খালি ওয়ার্ডস্লটগুলির মধ্য দিয়ে লুপ করুন এবং প্রত্যেকের জন্য বেশ কয়েকটি ক্যানসিডিটেট সলিউশন চেষ্টা করুন ("অর্ক-ধারাবাহিকতা বজায় রয়েছে কিনা তা নিশ্চিত করে", অর্থাত গ্রিডের এই পদক্ষেপের পরে একটি সমাধান রয়েছে যদি এই শব্দটি ব্যবহৃত হয়) এবং সেগুলি অনুসারে বাছাই করুন পরবর্তী পদক্ষেপের জন্য সর্বাধিক প্রাপ্যতা (অর্থাত্ পরবর্তী পদক্ষেপের সর্বাধিক সম্ভাব্য সমাধান রয়েছে যদি এই শব্দটি সেই স্থানে ব্যবহৃত হয়, ইত্যাদি)) (জটিলতা হে (এন * ম্যাক্স্যান্ডিডেটস ইউজড))
শব্দটি পূরণ করুন (এটিকে ভরাট হিসাবে চিহ্নিত করুন এবং দ্বিতীয় ধাপে যান)
কোনও পদক্ষেপ না পাওয়া গেলে পদক্ষেপের মানদণ্ডকে সন্তুষ্ট করে .3 কিছু পূর্ববর্তী পদক্ষেপের অন্য প্রার্থীর সমাধানের ব্যাকট্র্যাক করার চেষ্টা করুন (মানদণ্ড এখানে আলাদা হতে পারে) (জটিলতা ও (এন))
যদি ব্যাকট্র্যাক পাওয়া যায় তবে বিকল্পটি ব্যবহার করুন এবং ইতিমধ্যে ভরাট শব্দগুলির পুনঃনির্ধারণ করুন যা পুনরায় সেট করার প্রয়োজন হতে পারে (এগুলি আবার পূরণ না করে চিহ্নিত করুন) (জটিলতা ও (এন))
যদি কোনও ব্যাকট্র্যাক পাওয়া যায় না, তবে কোনও সমাধান পাওয়া যাবে না (কমপক্ষে এই কনফিগারেশন সহ, প্রাথমিক বীজ ইত্যাদি etc)
অন্যথায় যখন সমস্ত ওয়ার্ডলট পূরণ হয় আপনার একটি সমাধান হয়
এই অ্যালগরিদম সমস্যার সমাধান গাছের এলোমেলো ধারাবাহিক পদক্ষেপ করে। যদি কোনও পর্যায়ে একটি শেষ প্রান্ত থাকে তবে এটি পূর্ববর্তী নোডের ব্যাকট্র্যাক করে অন্য কোনও রুট অনুসরণ করে। ততক্ষণে কোনও সমাধান পাওয়া গেছে বা বিভিন্ন নোডের প্রার্থীদের সংখ্যা শেষ হয়ে গেছে।
ধারাবাহিকতার অংশটি নিশ্চিত করে যে সন্ধান পাওয়া একটি সমাধান আসলেই একটি সমাধান এবং এলোমেলো অংশটি বিভিন্ন মৃত্যুদণ্ডে বিভিন্ন সমাধান উত্পাদন করতে সক্ষম করে এবং গড়তেও আরও ভাল পারফরম্যান্স থাকে।
পুনশ্চ. এই সমস্ত (এবং অন্যদের) খাঁটি জাভাস্ক্রিপ্টে (সমান্তরাল প্রক্রিয়াকরণ এবং ডাব্লুওয়াইএসআইডাব্লুআইজি সহ) সক্ষমতায় প্রয়োগ করা হয়েছিল
PS2। অ্যালগরিদম একই সাথে একাধিক (পৃথক) সমাধান তৈরি করতে সহজেই সমান্তরাল করা যায়
আশাকরি এটা সাহায্য করবে
শুরু করার জন্য কেন কেবল একটি এলোমেলো সম্ভাব্য পদ্ধতির ব্যবহার করবেন না। একটি শব্দ দিয়ে শুরু করুন এবং তারপরে বারবার একটি এলোমেলো শব্দ বেছে নিন এবং আকারের সীমাবদ্ধতাগুলি ভঙ্গ না করে ধাঁধাটির বর্তমান অবস্থায় এটি ফিট করার চেষ্টা করুন you আপনি যদি ব্যর্থ হন তবে কেবল আবার শুরু করুন।
আপনি অবাক হয়ে যাবেন যে কোনও মন্টি কার্লো এর মত কাজ করে।
নিকফের উত্তর এবং ব্রায়ানের পাইথন কোডের উপর ভিত্তি করে এখানে কিছু জাভাস্ক্রিপ্ট কোড রয়েছে। জেএস-এ অন্য কারোর প্রয়োজন হলে কেবল এটি পোস্ট করা।
function board(cols, rows) { //instantiator object for making gameboards
this.cols = cols;
this.rows = rows;
var activeWordList = []; //keeps array of words actually placed in board
var acrossCount = 0;
var downCount = 0;
var grid = new Array(cols); //create 2 dimensional array for letter grid
for (var i = 0; i < rows; i++) {
grid[i] = new Array(rows);
}
for (var x = 0; x < cols; x++) {
for (var y = 0; y < rows; y++) {
grid[x][y] = {};
grid[x][y].targetChar = EMPTYCHAR; //target character, hidden
grid[x][y].indexDisplay = ''; //used to display index number of word start
grid[x][y].value = '-'; //actual current letter shown on board
}
}
function suggestCoords(word) { //search for potential cross placement locations
var c = '';
coordCount = [];
coordCount = 0;
for (i = 0; i < word.length; i++) { //cycle through each character of the word
for (x = 0; x < GRID_HEIGHT; x++) {
for (y = 0; y < GRID_WIDTH; y++) {
c = word[i];
if (grid[x][y].targetChar == c) { //check for letter match in cell
if (x - i + 1> 0 && x - i + word.length-1 < GRID_HEIGHT) { //would fit vertically?
coordList[coordCount] = {};
coordList[coordCount].x = x - i;
coordList[coordCount].y = y;
coordList[coordCount].score = 0;
coordList[coordCount].vertical = true;
coordCount++;
}
if (y - i + 1 > 0 && y - i + word.length-1 < GRID_WIDTH) { //would fit horizontally?
coordList[coordCount] = {};
coordList[coordCount].x = x;
coordList[coordCount].y = y - i;
coordList[coordCount].score = 0;
coordList[coordCount].vertical = false;
coordCount++;
}
}
}
}
}
}
function checkFitScore(word, x, y, vertical) {
var fitScore = 1; //default is 1, 2+ has crosses, 0 is invalid due to collision
if (vertical) { //vertical checking
for (i = 0; i < word.length; i++) {
if (i == 0 && x > 0) { //check for empty space preceeding first character of word if not on edge
if (grid[x - 1][y].targetChar != EMPTYCHAR) { //adjacent letter collision
fitScore = 0;
break;
}
} else if (i == word.length && x < GRID_HEIGHT) { //check for empty space after last character of word if not on edge
if (grid[x+i+1][y].targetChar != EMPTYCHAR) { //adjacent letter collision
fitScore = 0;
break;
}
}
if (x + i < GRID_HEIGHT) {
if (grid[x + i][y].targetChar == word[i]) { //letter match - aka cross point
fitScore += 1;
} else if (grid[x + i][y].targetChar != EMPTYCHAR) { //letter doesn't match and it isn't empty so there is a collision
fitScore = 0;
break;
} else { //verify that there aren't letters on either side of placement if it isn't a crosspoint
if (y < GRID_WIDTH - 1) { //check right side if it isn't on the edge
if (grid[x + i][y + 1].targetChar != EMPTYCHAR) { //adjacent letter collision
fitScore = 0;
break;
}
}
if (y > 0) { //check left side if it isn't on the edge
if (grid[x + i][y - 1].targetChar != EMPTYCHAR) { //adjacent letter collision
fitScore = 0;
break;
}
}
}
}
}
} else { //horizontal checking
for (i = 0; i < word.length; i++) {
if (i == 0 && y > 0) { //check for empty space preceeding first character of word if not on edge
if (grid[x][y-1].targetChar != EMPTYCHAR) { //adjacent letter collision
fitScore = 0;
break;
}
} else if (i == word.length - 1 && y + i < GRID_WIDTH -1) { //check for empty space after last character of word if not on edge
if (grid[x][y + i + 1].targetChar != EMPTYCHAR) { //adjacent letter collision
fitScore = 0;
break;
}
}
if (y + i < GRID_WIDTH) {
if (grid[x][y + i].targetChar == word[i]) { //letter match - aka cross point
fitScore += 1;
} else if (grid[x][y + i].targetChar != EMPTYCHAR) { //letter doesn't match and it isn't empty so there is a collision
fitScore = 0;
break;
} else { //verify that there aren't letters on either side of placement if it isn't a crosspoint
if (x < GRID_HEIGHT) { //check top side if it isn't on the edge
if (grid[x + 1][y + i].targetChar != EMPTYCHAR) { //adjacent letter collision
fitScore = 0;
break;
}
}
if (x > 0) { //check bottom side if it isn't on the edge
if (grid[x - 1][y + i].targetChar != EMPTYCHAR) { //adjacent letter collision
fitScore = 0;
break;
}
}
}
}
}
}
return fitScore;
}
function placeWord(word, clue, x, y, vertical) { //places a new active word on the board
var wordPlaced = false;
if (vertical) {
if (word.length + x < GRID_HEIGHT) {
for (i = 0; i < word.length; i++) {
grid[x + i][y].targetChar = word[i];
}
wordPlaced = true;
}
} else {
if (word.length + y < GRID_WIDTH) {
for (i = 0; i < word.length; i++) {
grid[x][y + i].targetChar = word[i];
}
wordPlaced = true;
}
}
if (wordPlaced) {
var currentIndex = activeWordList.length;
activeWordList[currentIndex] = {};
activeWordList[currentIndex].word = word;
activeWordList[currentIndex].clue = clue;
activeWordList[currentIndex].x = x;
activeWordList[currentIndex].y = y;
activeWordList[currentIndex].vertical = vertical;
if (activeWordList[currentIndex].vertical) {
downCount++;
activeWordList[currentIndex].number = downCount;
} else {
acrossCount++;
activeWordList[currentIndex].number = acrossCount;
}
}
}
function isActiveWord(word) {
if (activeWordList.length > 0) {
for (var w = 0; w < activeWordList.length; w++) {
if (word == activeWordList[w].word) {
//console.log(word + ' in activeWordList');
return true;
}
}
}
return false;
}
this.displayGrid = function displayGrid() {
var rowStr = "";
for (var x = 0; x < cols; x++) {
for (var y = 0; y < rows; y++) {
rowStr += "<td>" + grid[x][y].targetChar + "</td>";
}
$('#tempTable').append("<tr>" + rowStr + "</tr>");
rowStr = "";
}
console.log('across ' + acrossCount);
console.log('down ' + downCount);
}
//for each word in the source array we test where it can fit on the board and then test those locations for validity against other already placed words
this.generateBoard = function generateBoard(seed = 0) {
var bestScoreIndex = 0;
var top = 0;
var fitScore = 0;
var startTime;
//manually place the longest word horizontally at 0,0, try others if the generated board is too weak
placeWord(wordArray[seed].word, wordArray[seed].displayWord, wordArray[seed].clue, 0, 0, false);
//attempt to fill the rest of the board
for (var iy = 0; iy < FIT_ATTEMPTS; iy++) { //usually 2 times is enough for max fill potential
for (var ix = 1; ix < wordArray.length; ix++) {
if (!isActiveWord(wordArray[ix].word)) { //only add if not already in the active word list
topScore = 0;
bestScoreIndex = 0;
suggestCoords(wordArray[ix].word); //fills coordList and coordCount
coordList = shuffleArray(coordList); //adds some randomization
if (coordList[0]) {
for (c = 0; c < coordList.length; c++) { //get the best fit score from the list of possible valid coordinates
fitScore = checkFitScore(wordArray[ix].word, coordList[c].x, coordList[c].y, coordList[c].vertical);
if (fitScore > topScore) {
topScore = fitScore;
bestScoreIndex = c;
}
}
}
if (topScore > 1) { //only place a word if it has a fitscore of 2 or higher
placeWord(wordArray[ix].word, wordArray[ix].clue, coordList[bestScoreIndex].x, coordList[bestScoreIndex].y, coordList[bestScoreIndex].vertical);
}
}
}
}
if(activeWordList.length < wordArray.length/2) { //regenerate board if if less than half the words were placed
seed++;
generateBoard(seed);
}
}
}
function seedBoard() {
gameboard = new board(GRID_WIDTH, GRID_HEIGHT);
gameboard.generateBoard();
gameboard.displayGrid();
}
আমি দুটি সংখ্যা তৈরি করব: দৈর্ঘ্য এবং স্ক্র্যাবল স্কোর। ধরে নিন যে একটি কম স্ক্র্যাবল স্কোর মানে এর সাথে যোগ দেওয়া সহজ (কম স্কোর = প্রচুর প্রচলিত চিঠি)। দৈর্ঘ্য অবতরণ এবং স্ক্র্যাবল স্কোর আরোহী অনুসারে তালিকাটি সাজান।
এরপরে, কেবল তালিকাটি নীচে যান। শব্দটি যদি বিদ্যমান শব্দের সাথে অতিক্রম না করে (প্রতিটি শব্দের বিপরীতে যথাক্রমে তার দৈর্ঘ্য এবং স্ক্র্যাবল স্কোর পরীক্ষা করে দেখুন), তবে এটিকে কাতারে রাখুন এবং পরবর্তী শব্দটি পরীক্ষা করুন check
ধুয়ে ফেলুন এবং পুনরাবৃত্তি করুন এবং এটি ক্রসওয়ার্ড তৈরি করবে।
অবশ্যই, আমি নিশ্চিত যে এটি হ'ল (এন!) এবং এটি আপনার জন্য ক্রসওয়ার্ডটি সম্পূর্ণ করার গ্যারান্টিযুক্ত নয় তবে সম্ভবত কেউ এটির উন্নতি করতে পারে।
আমি এই সমস্যাটি নিয়ে ভাবছিলাম আমার জ্ঞানটি হ'ল সত্যই ঘন ক্রসওয়ার্ডটি তৈরি করতে আপনি আশা করতে পারবেন না যে আপনার সীমিত শব্দ তালিকার পরিমাণ যথেষ্ট। সুতরাং, আপনি একটি অভিধান নিতে এবং এটি একটি "ত্রি" ডেটা কাঠামোতে স্থাপন করতে চাইতে পারেন। এটি আপনাকে এমন শব্দগুলি সহজেই সন্ধান করতে দেয় যা ফাঁকা জায়গাগুলি পূরণ করে। একটি ট্রাইতে, এটি একটি ট্র্যাভারসাল বাস্তবায়নের পক্ষে মোটামুটি দক্ষ, যা বলে, আপনাকে "c? T" ফর্মের সমস্ত শব্দ দেয়।
সুতরাং, আমার সাধারণ চিন্তাভাবনাটি হ'ল: কিছু লোকেরা এখানে নিম্ন-ঘনত্বের ক্রস তৈরির জন্য বর্ণিত হিসাবে তুলনামূলকভাবে কিছু জোরের পদ্ধতির তৈরি করুন এবং অভিধানের শব্দের সাথে ফাঁকা স্থান পূরণ করুন fill
অন্য কেউ যদি এই পদ্ধতি গ্রহণ করে থাকে তবে দয়া করে আমাকে জানান।
আমি ক্রসওয়ার্ড জেনারেটর ইঞ্জিনের চারপাশে খেলছিলাম এবং আমি এটি সবচেয়ে গুরুত্বপূর্ণ হিসাবে পেয়েছি:
0।!/usr/bin/python
ক। allwords.sort(key=len, reverse=True)
খ। কার্সারের মতো কিছু আইটেম / অবজেক্ট তৈরি করুন যা ম্যাট্রিক্সের চারপাশে চলবে সহজ অভিযোজনের জন্য যদি না আপনি পরে এলোমেলো পছন্দ দ্বারা পুনরাবৃত্তি করতে চান না।
প্রথমটি, প্রথম জোড়াটি বেছে নিন এবং এটিকে 0,0 থেকে নীচে রেখে দিন; প্রথমটিকে আমাদের বর্তমান ক্রসওয়ার্ড 'নেতা' হিসাবে সংরক্ষণ করুন।
ক্রসটি অর্ডার দ্বারা তির্যক বা এলোমেলোভাবে বৃহত্তর তির্যক সম্ভাব্যতা সহ পরবর্তী ফাঁকা ঘরে সরিয়ে নিন
শব্দের উপর পুনরাবৃত্তি করুন এবং সর্বাধিক শব্দের দৈর্ঘ্য নির্ধারণ করতে ফাঁকা জায়গার দৈর্ঘ্য ব্যবহার করুন:
temp=[]
for w_size in range( len( w_space ), 2, -1 ) :
# t
for w in [ word for word in allwords if len(word) == w_size ] :
#
if w not in temp and putTheWord( w, w_space ) :
#
temp.append( w )
আমি ব্যবহৃত স্থানের বিরুদ্ধে শব্দটির তুলনা করতে যেমন:
w_space=['c','.','a','.','.','.'] # whereas dots are blank cells
# CONVERT MULTIPLE '.' INTO '.*' FOR REGEX
pattern = r''.join( [ x.letter for x in w_space ] )
pattern = pattern.strip('.') +'.*' if pattern[-1] == '.' else pattern
prog = re.compile( pattern, re.U | re.I )
if prog.match( w ) :
#
if prog.match( w ).group() == w :
#
return True
প্রতিটি সফলভাবে ব্যবহৃত শব্দের পরে, দিক পরিবর্তন করুন। সমস্ত ঘর পূর্ণ হয়ে যাওয়ার সময় লুপ করুন বা আপনি শব্দগুলির বাইরে চলেছেন বা পুনরাবৃত্তির সীমা দ্বারা:
# CHANGE ALL WORDS LIST
inexOf1stWord = allwords.index( leading_w )
allwords = allwords[:inexOf1stWord+1][:] + allwords[inexOf1stWord+1:][:]
... এবং আবার নতুন ক্রসওয়ার্ড পুনরাবৃত্তি করুন।
পূরণের স্বাচ্ছন্দ্য এবং কিছু অনুমানের ক্যালক দিয়ে স্কোরিং সিস্টেমটি তৈরি করুন। বর্তমান ক্রসওয়ার্ডের জন্য স্কোর দিন এবং পরে স্কোরটি আপনার স্কোরিং সিস্টেমের দ্বারা সন্তুষ্ট হলে তৈরি ক্রসওয়ার্ডগুলির তালিকায় এটি যুক্ত করুন narrow
প্রথম পুনরাবৃত্তি সেশনের পরে পুনরায় কাজ শেষ করতে তৈরি ক্রসওয়ার্ডগুলির তালিকা থেকে পুনরাবৃত্তি করুন।
আরও বেশি পরামিতি ব্যবহার করে গতি একটি বিশাল গুণক দ্বারা উন্নত করা যেতে পারে।
আমি সম্ভাব্য ক্রসগুলি জানার জন্য প্রতিটি শব্দের দ্বারা ব্যবহৃত প্রতিটি অক্ষরের একটি সূচক পেতে পারি। তারপরে আমি সবচেয়ে বড় শব্দটি বেছে নেব এবং এটি বেস হিসাবে ব্যবহার করব। পরবর্তী বড়টি নির্বাচন করুন এবং এটি ক্রস করুন। পাখলান পুনরাবৃত্তি. এটি সম্ভবত একটি এনপি সমস্যা।
আর একটি ধারণা জেনেটিক অ্যালগরিদম তৈরি করছে যেখানে শক্তি মেট্রিক হ'ল আপনি গ্রিডে কত শব্দ রাখতে পারেন।
একটি নির্দিষ্ট তালিকাটি জানার সময় আমি যে শক্ত অংশটি খুঁজে পাই তা হ'ল সম্ভবত পারা যায় না।
এটি হার্ভার্ড থেকে এআই সিএস 50 কোর্সে একটি প্রকল্প হিসাবে উপস্থিত হয় । ধারণাটি হ'ল ক্রসওয়ার্ড জেনারেশন সমস্যাটিকে একটি সীমাবদ্ধ তৃপ্তির সমস্যা হিসাবে চিহ্নিত করা এবং অনুসন্ধানের স্থান হ্রাস করার জন্য বিভিন্ন হিউরিস্টিক্সের সাথে ব্যাকট্র্যাকিংয়ের মাধ্যমে সমাধান করা।
শুরু করতে আমাদের কয়েকটি ইনপুট ফাইলের প্রয়োজন:
`
###_####_#
____####_#
_##_#_____
_##_#_##_#
______####
#_###_####
#_##______
#_###_##_#
_____###_#
#_######_#
##_______#
`
একটি ইনপুট শব্দভাণ্ডার (শব্দের তালিকা / অভিধান) যা থেকে প্রার্থীর শব্দগুলি বেছে নেওয়া হবে (নীচের চিত্রের মতো)।
a
abandon
ability
able
abortion
about
above
abroad
absence
absolute
absolutely
...
এখন সিএসপি সংজ্ঞায়িত করা হয়েছে এবং নিম্নলিখিত হিসাবে সমাধান করা হবে:
নিম্নলিখিতটি সিএসপি সমাধানের আলগোরিদিম ব্যবহার করে প্রাপ্ত আউটপুট দেখায়:
`
███S████D█
MUCH████E█
E██A█AGENT
S██R█N██Y█
SUPPLY████
█N███O████
█I██INSIDE
█Q███E██A█
SUGAR███N█
█E██████C█
██OFFENSE█
`
নিম্নলিখিত অ্যানিমেশন ব্যাকট্র্যাকিং পদক্ষেপগুলি দেখায়:
এখানে বাংলা (বাংলা) ভাষার শব্দ-তালিকা সহ আরও একটি রয়েছে:
আমি এই সমস্যার একটি জাভাস্ক্রিপ্ট / jQuery সমাধান কোড আপ করেছি:
নমুনা ডেমো: http://www.earthfluent.com / ক্রসওয়ার্ড-puzzle- demo.html
সোর্স কোড: https://github.com/HoldOffHunger/jquery-crossword-puzzle-generator
আমি ব্যবহৃত অ্যালগরিদমের উদ্দেশ্য:
আমি ব্যবহৃত আলগোরিদিম বর্ণনা করব:
যেগুলি একটি সাধারণ চিঠি ভাগ করে দেয় সে অনুযায়ী শব্দগুলি একসাথে ভাগ করুন।
এই গোষ্ঠীগুলি থেকে, একটি নতুন ডেটা স্ট্রাকচারের সেট তৈরি করুন ("ওয়ার্ড ব্লকস"), এটি একটি প্রাথমিক শব্দ (যা অন্য সমস্ত শব্দের মধ্য দিয়ে চলে) এবং তারপরে অন্য শব্দগুলি (যা প্রাথমিক শব্দের মধ্য দিয়ে চলে)।
ক্রসওয়ার্ড ধাঁধাটির খুব উপরের-বাম অবস্থানে এই শব্দ ব্লকগুলির মধ্যে প্রথমটি দিয়ে ক্রসওয়ার্ড ধাঁধাটি শুরু করুন।
ক্রসওয়ার্ড ধাঁধাটির ডান-নীচের বেশিরভাগ অবস্থান থেকে শুরু করে বাক্য অবরুদ্ধ শব্দের জন্য, উপরের দিকে এবং বাম দিকে সরান, যতক্ষণ না ভরাবার জন্য আর কোনও উপলভ্য থাকে না। বাম দিকের চেয়ে উপরে খালি কলামগুলি যদি উপরে থাকে তবে উপরের দিকে সরান এবং বিপরীতে।
var crosswords = generateCrosswordBlockSources(puzzlewords);
। শুধু এই মানটি লগ কনসোল। ভুলে যাবেন না, গেমটিতে একটি "চিট-মোড" রয়েছে, যেখানে অবিলম্বে মান পেতে আপনি কেবল "উত্তর প্রকাশ করুন" ক্লিক করতে পারেন।