IBM Sterling map editor: is there a way to sort OID in 204 EDI - ibm-sterling

IBM Sterling map editor: is there a way to sort OID in 204 EDI
I need some help/ideas on how to do this
This is the input file
ISA*...
GS*...
...
S5*2*CU*34140*L~
G62*68*20220531~
AT8*G*L*34140*4437~
PLD*27~
N1*ST*COSTCO STORE AAAA*93*0000000761~
N3*1013 HOMER STREET ~
N4*CITY*CA*90210~
OID*SO1241*135020070**PC*1*L*0~
L5**Certificate Of Sale~
AT8*G*L*0*1~
OID*SO1241*135020070**PC*24*L*0~
L5**AIRBAG~
AT8*G*L*0*24~
OID*SO1157*135020014**PC*1*L*0~
L5**Certificate Of Sale~
AT8*G*L*0*1~
OID*SO1241*135020070**PC*1080*L*30720~
L5**APPLES 2 lb~
AT8*G*L*30720*3840~
OID*SO1157*135020014**PC*1070*L*3420~
L5**ORANGES 12 oz~
AT8*G*L*3420*570~
OID*SO1241*135020070**PC*1*L*0~
L5**GPS TRACKER~
AT8*G*L*0*1~
L3*...
SE*...
GE*...
IEA*...
And this is the output file I want to get, EDI to POSITIONAL
HDR1: PO 135020070
ITEM: Certificate Of Sale,QTY 1
ITEM: AIRBAG,QTY 24
ITEM: APPLES 2 lb,QTY 1080
ITEM: GPS TRACKER,QTY 1
HDR1: PO 135020014
ITEM: Certificate Of Sale,QTY 1
ITEM: ORANGES 12 oz,QTY 1070
Currently this is what my MAP is doing
HDR1: PO 135020070
ITEM: Certificate Of Sale,QTY 1
ITEM: AIRBAG,QTY 24
HDR1: PO 135020014
ITEM: Certificate Of Sale,QTY 1
HDR1: PO 135020070
ITEM: APPLES 2 lb,QTY 1080
HDR1: PO 135020014
ITEM: ORANGES 12 oz,QTY 1070
HDR1: PO 135020070
ITEM: GPS TRACKER,QTY 1
This is my current code (extended rule on OID), that produce the map above
if sPONum = "" | (sPONum != "" & sPONum != #0324) then
begin
//CREATE PO HEADER
sPONum = #0324;
iCU = iCU + 1;
$POGroup[iCU].#TEMP_DUNS = sDUNS;
$POGroup[iCU].#PONumber = #0324;
//CREATE ITEM LINE
//RESET ITEM LINE FOR EACH PO
iItem = 0;
iItem = iItem + 1;
iOID = iOID + 1;
$TEMP_ITEM[iCU][iItem].#TEMP_Qty = #0380:4;
$TEMP_ITEM[iCU][iItem].#TEMP_Description = $0320_L5[iS5][iOID][1].#0079:2;
end
else
begin
iItem = iItem + 1;
iOID = iOID + 1;
$TEMP_ITEM[iCU][iItem].#TEMP_Qty = #0380:4;
$TEMP_ITEM[iCU][iItem].#TEMP_Description = $0320_L5[iS5][iOID][1].#0079:2;
end
Any tips and pointers for master of map editor out there
greatly appreciative of your help
Cheers

the spaghetti code that I come up with.
I am sure there is a more efficient way.
Anyone may suggest to make this more elegant.
It is not the best , but it work for my purpose. Thanks
iOID = iOID + 1;
iFOUND = 0;
iCount = 0;
While iCount < iOID DO
begin
iCount = iCount + 1;
//PO HDR FOUND
if $POGroup[iCount].#PONumber = #0324 & iFOUND = 0 then
begin
iFOUND = iCount;
end
end
if iFOUND = 0 then
begin
//CREATE PO HEADER
iNewPO = iNewPO + 1;
$POGroup[iNewPO].#PONumber = #0324;
$POGroup[iNewPO].#TEMP_DUNS = sDUNS;
$POGroup[iNewPO].#TEMP_PODt = sPODt;
$POGroup[iNewPO].#STATUS_CODE = sStatusCode;
$POGroup[iNewPO].#SCAC = sSCAC;
$POGroup[iNewPO].#SID = sSID;
$POGroup[iNewPO].#SONum = #0127:7;
strdate($0300_S5[iS5].#0373:2,"%Y%m%d", $POGroup[iNewPO].#DeliveryDt);
$TEMP_MESSAGE[iNewPO][1].#MSG = sShipType;
//CREATE FIRST ITEM LINE
//RESET FLAT FILE ITEM LINE FOR EACH PO
iItem = 1;
$TEMP_ITEM[iNewPO][iItem].#TEMP_Qty = #0380:4;
$TEMP_ITEM[iNewPO][iItem].#TEMP_Description = $0320_L5[iS5][iOID][1].#0079:2;
end
else
begin
//FIND MAX ITEM LINE FOR FOUND PO INDEX
iItmMax = 0;
iCount = 0;
While iCount < iOID DO
begin
iCount = iCount + 1;
//Loop to each item and find the max
if $TEMP_ITEM[iFOUND][iCount].#TEMP_Qty != "" then iItmMax = iCount;
end
//SET THE MAX ITEM PLUS ONE
iItem = iItmMax + 1;
//CREATE ITEM LINE
$TEMP_ITEM[iFOUND][iItem].#TEMP_Qty = #0380:4;
$TEMP_ITEM[iFOUND][iItem].#TEMP_Description = $0320_L5[iS5][iOID][1].#0079:2;
end

Related

Creating instance for non-existing object: <somenumber> | What Did I Do Wrong?

Every time I run my little game, it throws me the following, fatal, error:
ERROR in
action number 2
of Trigger Event:
for object obj_y:
Creating instance for non-existing object: 100012
I have no idea what's causing it. The only time I use obj_y, is in one file. When I comment that part out, it still keeps nagging it's non-existing.
My code:
var randomxnumber;
var randomynumber;
var randomarraynumber;
var array;
var snelheid;
snelheid = 3.5;
array[0] = obj_a;
array[1] = obj_b;
array[2] = obj_c;
array[3] = obj_d;
array[4] = obj_e;
array[5] = obj_f;
array[6] = obj_g;
array[7] = obj_h;
array[8] = obj_i;
array[9] = obj_j;
array[10] = obj_k;
array[11] = obj_l;
array[12] = obj_m;
array[13] = obj_n;
array[14] = obj_o;
array[15] = obj_p;
array[16] = obj_q;
array[17] = obj_r;
array[18] = obj_s;
array[19] = obj_t;
array[20] = obj_u;
array[21] = obj_v;
array[22] = obj_w;
array[23] = obj_x;
array[24] = obj_y;
array[25] = obj_z;
randomxnumber = random_range(0, 50);
randomynumber = random_range(-10, -50);
for (int = 0; int < 20; int += 1){
if(randomxnumber >= window_get_width()){
randomxnumber -= 100;
} else {
randomxnumber += 50;
}
randomynumber -= 50;
array[int] = instance_create(randomxnumber, randomynumber, array[random_range(0, 26)]);
with(array[int]){
vspeed = snelheid;
}
}
My obj_y object:
Quick note, I'm on GameMaker 8.1 Standard. I'm I being stupid and just missing something?
It's very strange code, I don't understand what you trying to do.
Although there are two errors.
array[random_range(0, 26)]
should be
array[irandom_range(0, 25)
GM rounds array's index, so if value is more than 25 (25.1, etc) you will have out of array bounds.
Second.
array[int] = instance_create(...)
There instance's id will be stored into array. Not object's id. But instance_create requires object index. You can get object's index using object_index variable:
array[int] = instance_create(randomxnumber, randomynumber, array[irandom_range(0, 25)].object_index);

How to create Query using IN?

I need to collect data and add it to temporary table in AX 2012 R3 using X++.
This is the Query on SQL
select store, receiptid, itemid, str(qty,16,0) as Qty, str(price,16,0) as Price, str(DISCAMOUNT,16,0) DiscAmount, str(taxamount,16,0) SalesTaxAmount ,convert(date, transdate) transdate, DATAAREAID from RETAILTRANSACTIONSALESTRANS
where DATAAREAID in ('5740','5760') and transdate >='2016-03-21' and transdate <='2016-03-27' and store in ('JTJDRN1','JNUSADP','JOFFICE')
and INVENTSTATUSSALES='2' and itemid in ('10010038') and receiptid in (select receiptid from RETAILTRANSACTIONPAYMENTTRANS where transdate >='2016-03-21' and transdate <='2016-03-27')
order by transdate
User can input transDate, itemid and storeid
this is what form looks like
this is my code so far
private void RetailPromoReport()
{
str receiptId, curDatetxt,fileLocation, filePath, itemtxt, startPtxt, endPtxt,
storetxt, item_txt, item2, receiptId2, rcptid_txt, store_txt, store2;
FileName fileName;
str 50 item, itemid, store;
container items, receiptid_con, stores;
int i,x, ware, itm, tot, y,z, rcptLen, storeLen;
Date emptyDate, startP, endP;
RetailTransactionPaymentTrans rtpt;
RetailTransactionSalesTrans rtst;
ReportRetailTemp rrpi_tmp, rrpi_tmp2;
QueryBuildRange qbr1, qbr2, qbr3, qbr4, qbr5;
QueryRun queryRun;
Query query, query2;
QueryBuildDataSource qbdsRetailTransactionPaymentTrans, qbdsRetailTransactionSalesTrans;
RecordInsertList recordILCRppi_tmp = new RecordInsertList(tableNum(ReportRetailTemp),false,false,false,false,false,rrpi_tmp);
;
startP = DateFrom.dateValue();
endP = DateTo.dateValue();
tot = 0;
delete_from rrpi_tmp;
while select receiptId from rtpt group by rtpt.receiptId where rtpt.transDate >= startP && rtpt.transDate <= endP
{
receiptid_con += rtpt.receiptId;
}
query = new Query();
qbdsRetailTransactionSalesTrans = query.addDataSource(tableNum(RetailTransactionSalesTrans));
qbr1 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans,TransDate));
qbr1.value(strfmt('(%3.transDate>=%1) && (%3.transDate<=%2)',Date2StrXpp(startP),Date2StrXpp(endP),qbdsRetailTransactionSalesTrans.name()));
qbr2 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans,inventStatusSales));
qbr2.value(queryValue(enum2str(RetailInventStatusSales::Posted)));
items = msCtrlCust.getSelectedFieldValues();
itemtxt = multilookupItem.valueStr();
stores = msCtrlStore.getSelectedFieldValues();
storetxt = multilookupStore.valueStr();
if(itemtxt != "")
{
item_txt = conPeek(items,1);
item2 = strFmt('(%2.itemId == "%1") ',queryValue(conPeek(items,1)),qbdsRetailTransactionSalesTrans.name());
itm = conlen(items);
if(itm > 1)
{
for (i = 2; i <= itm;i++)
{
item = conPeek(items,i);
item2 = strFmt('%1 || (%3.itemId == "%2") ',item2, queryValue(item),qbdsRetailTransactionSalesTrans.name());
}
}
qbr3 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans, itemId));
qbr3.value(strFmt("%1",item2));
}
rcptLen = conlen(receiptid_con);
receiptId2 = strFmt('(%2.receiptId == "%1") ',queryValue(conPeek(receiptid_con,1)),qbdsRetailTransactionSalesTrans.name());
if(rcptLen > 1)
{
for (y = 2; y <= rcptLen; y++)
{
rcptid_txt = conPeek(receiptid_con,y);
receiptId2 = strFmt('%1 || (%3.receiptId == "%2") ',receiptId2, queryValue(rcptid_txt),qbdsRetailTransactionSalesTrans.name());
}
}
qbr4 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans, receiptId));
qbr4.value(strFmt("%1",receiptId2));
if(storetxt != '')
{
store_txt = conPeek(stores,1);
store2 = strFmt('(%2.store == "%1") ',queryValue(conPeek(stores,1)),qbdsRetailTransactionSalesTrans.name());
storeLen = conlen(stores);
if(storeLen > 1)
{
for (z = 2; z <= storeLen;z++)
{
store = conPeek(stores,z);
store2 = strFmt('%1 || (%3.store == "%2") ',store2, queryValue(store),qbdsRetailTransactionSalesTrans.name());
}
}
qbr5 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans, store));
qbr5.value(strFmt("%1",store2));
}
qbdsRetailTransactionSalesTrans.addSortField(fieldNum(RetailTransactionSalesTrans, transDate),SortOrder::Ascending);
qbdsRetailTransactionSalesTrans.addSortField(fieldNum(RetailTransactionSalesTrans, itemId),SortOrder::Ascending);
queryRun = new QueryRun(query);
while (queryRun.next())
{
rtst = queryRun.getNo(1);
rrpi_tmp.store = rtst.store;
rrpi_tmp.receiptId = rtst.receiptId;
rrpi_tmp.itemId = rtst.itemId;
rrpi_tmp.qty = rtst.qty;
rrpi_tmp.price = rtst.price;
rrpi_tmp.discAmount = rtst.discAmount;
rrpi_tmp.SalestaxAmount = rtst.taxAmount;
rrpi_tmp.transDate = rtst.transDate;
recordILCRppi_tmp.add(rrpi_tmp);
tot++;
}
ttsBegin;
recordILCRppi_tmp.insertDatabase();
ttsCommit;
ReportRetailTemp_ds.research(true);
ReportRetailTemp_ds.refresh();
if(tot > 0)
{
Box::info(strFmt("%1 row data",tot));
}
else
{
Box::info(strFmt("No Data",tot));
}
}
My code doesn't show any error in short period but because receiptId is stored in str,
receiptId2 = strFmt('%1 || (%3.receiptId == "%2") ',receiptId2, queryValue(rcptid_txt),qbdsRetailTransactionSalesTrans.name());
there is limitation and show error for long periode
Can someone make my code more efficient and
is there any way to create Query in x++ that have same function like "IN" on SQL
You have two options:
You can use more than one query range for the same field; it will automatically count as an or
for (i = conLen(items); i > 0; i--)
qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans, itemId)).value(queryValue(conPeek(items,i)));
You may need special handling, if the container is empty!
Often it is better to use an (exists) join instead
ds = qbdsRetailTransactionSalesTrans.addDatasource(tableNum(RetailTransactionPaymentTrans));
ds.joinMode(JoinMode::ExistsJoin);
ds.relations(true); // Or do ds.addLink(...) etc.
I am not sure I follow the correct logic here :)
If you need to do crosscompany selections, do so using the interface for that:
qbdsRetailTransactionSalesTrans.allowCrossCompany(true);
qbdsRetailTransactionSalesTrans.addCompanyRange('5740');
qbdsRetailTransactionSalesTrans.addCompanyRange('5760');

Pass same parameters multiple times in SQLitecommand

I like to run below query :
select
lon, lat
from rdf_city_poi p, rdf_location l
where p.location_id = l.location_id and p.poi_id = ?
union all select
lon, lat
from rdf_poi_address p, rdf_location l
where p.location_id = l.location_id and p.poi_id = ?
union all select
lon, lat
from xtdp_poi_address pa, xtdp_location l
where pa.location_id=l.location_id and pa.poi_id= ?
As you can see it's required 3 times same parameter and it's value
parameter ("?") ::: value (ex. 12345)
I have written below code which take argument but only 1 time.
int Carto_id = Convert.ToInt32(dtsqlquery2.Rows[k][0]);
string selectpoly = xNodelatlongquery2.Replace("\r\n", string.Empty);
//SQLiteCommand selectpolygon = new SQLiteCommand(selectpoly + Carto_id, con);
int countparameters = selectpoly.Split('?').Length - 1;
SQLiteCommand selectpolygon = new SQLiteCommand(selectpoly, con);
//var paramaters = new string[countparameters];
//SQLiteParameter[] parameters = new SQLiteParameter[countparameters];
for (int i = 0; i < countparameters; i++)
{
//SQLiteParameter[] parame = new SQLiteParameter[]{
//new SQLiteParameter("?", Carto_id)};
//paramaters[i] = string.Format("?", Carto_id);
//selectpolygon.Parameters.AddWithValue(paramaters[i], Carto_id);
selectpolygon.Parameters.AddWithValue("?", Carto_id);
}
//selectpolygon.Parameters.AddRange(paramaters);
SQLiteDataReader dataReaderpoly = selectpolygon.ExecuteReader();
DataSet ds1 = new DataSet();
You can see I have tried with some logics but they are not satisfying my requirement.
How can I Add array of parameters into command of my logic ?
In SQLite, you can give parameters a number explicitly:
... WHERE x = ?1 OR y = ?1 AND z <> ?1 ...
or give it a name:
... WHERE x = :PoiID OR y = :PoiID AND z <> :PoiID ...

How can we filter text from array

I have an array which return data in size like 3,6,9,12,15.. (multiplication of 3)
DataTable dt = new DataTable();
string GridData = ViewState["ShowItem"].ToString();
string[] FilterData = GridData.Split('^');
Above array return data like..
FilterData [0] = "Pizza"; (Item)
FilterData [1] = "2$"; (Price)
FilterData [2] = "2"; (Quantity)
FilterData [3] = "Burger";
FilterData [4] = "5$";
FilterData [5] = "1";
FilterData [6] = "Cesa";
FilterData [7] = "7$";
FilterData [8] = "3";
now I want to enter above data as column wise in database like:
Item Price Quantity Total(Price*Quantity)
now I want to run a loop that add data of particular field like:
for (int nIndex = 0; nIndex < FilterData.Length; nIndex++)
{
DataRow drow = dt.NewRow();
drow["ProductItem"] = FilterData[nIndex].ToString(); (Add all Item)
drow["Cost"] = FilterData[nIndex].ToString(); (Add all Cost)
drow["Quantity"] = FilterData[nIndex].ToString(); (Add all Quantity)
double Total= Convert.ToDouble(FilterData[nIndex].ToString()) * Convert.ToInt32(FilterData[nIndex].ToString()); (Add all cost*Quantity)
drow["Total"] = Total;
dt.Rows.Add(drow);
}
So can anybody help me how could I run the loop so it add data to particular column like:
Item Price Quantity Total(Price*Quantity)
Pizza 2 2 4
Burger 5 1 5
Cesa 7 3 21
You need to increment nIndex by 3 each time, access each member by it's offset from nIndex:
for (int nIndex = 0; nIndex < FilterData.Length; nIndex += 3)
{
DataRow drow = dt.NewRow();
drow["ProductItem"] = FilterData[nIndex]; // Item
var cost = FilterData[nIndex + 1]; // Cost
var qty = FilterData[nIndex + 2]; // Quantity
drow["Cost"] = cost;
drow["Quantity"] = qty;
double Total =
Convert.ToDouble(cost.Remove(cost.Length - 1)) * // remove $
Convert.ToInt32(qty); // Total
drow["Total"] = Total;
dt.Rows.Add(drow);
}

Complex process of making a typical Housie/Bingo game ticket?

I'm trying to create a typical Housie/Bingo Game ticket in Asp.net 2.0 (VB). But, not being succeeded. Ticket contains 3 row with 9 columns. Total 27 blocks, and it must be only 15 should be fill outta those 27. and each column contains value like 1st column should be between 1-10 and 2nd must have random values between 11-20.. It doesn't matter how many blocks filled in each column.. 1 is must, no single column should be blank, all 9 columns must be filled, some have all 3 blocks filled, some have 1 with total of 15 blocks filled in whole ticket. with random numbers..
Guys here was the typical housie ticket specification.. Please help me out generating a ticket like this. I've tried but, not being that much succeeded, I get whole column blank and validating columns.. takes extra load on system. please find me the way to make it.
You need deterministic algorithm
First redefine your requirements:
Every column should have at least 1 number, so no column should be completely blank
First column should have numbers from 1..10, second 11..20, third 21..30 and so on to the ninth column having from 81..90
only 15 numbers needed to fill the ticket
Additional requirement: Every row should have 5 numbers
This is how I'd do it:
First select 9 randoms (to satisfy first requirement)
1..10 - one random number from this range
11..20 - one random number from this range
...
81..90 - one random number from this range
Prepare an array (selectNums) of numbers 1..90 and remove all selected in step 1
Loop
get a random number from the selectNums array
add it to your ticket and remove it from the selectNums aray
if selected number fills a column of three then remove all numbers from that range from the selectNums array.
Go back to step 1 in the loop
This algorithm will take you exactly 9 steps + 6 steps in the loop so it's deterministic which is better for the processor utilization. And it also fills your ticket with up to three numbers per column and not less than 1 (if I understood your requirements due too poor english in the question).
Yo when you select random numbers you always select a number between 0 and selectNums array length which will give you position in array where you have to take a number from.
Additonal functionality to create the actual ticket
Above steps will get you to a point where you will get exactly 15 numbers with at most 3 from the same ten numbers range. Fine. All you have to do now is to create your ticket.
define 3 variables: row1Count, row2Count and row3Count and set them all to 0.
Fill the ticket by starting from the fully filled columns (all three numbers):
Get the first full column and fill it up in the ticket while also incrementing all three variables by one.
Remove these numbers from the selectNums array.
Go back to step 2.1.
Fill the ticket with columns with two numbers:
Get the first two numbers column. Fill them in the ticket by using three possible permutations of filling them in (1&2, 2&3, 1&3). Fill the first pair using the first permutation, second one with the second and so on. Don't forget to increment corresponding row counter variables.
remove those two numbers from selectNums array
Go back to step 3.1.
Fill the ticket with single number columns (those that have just one number):
Get the first number from selectNums array and put it in the row with the smallest count and put in on the ticket in that particular row. When there are at least two rows with the same count, you can select whichever you prefer by either selecting one randomly or taking the first one (quickest).
Remove the number from selectNums array
Go back to 4.1.
This part should get you to fully filled ticket with all columns having at least one number and all rows containing exactly 5 numbers in total.
If smaller numbers are not allowed to be under larger ones, you can always add an additional step to this process and reorder numbers in those columns that have more than just one number in it.
One final observation
This solution has been simplified by using arrays and counters. You could of course create a complete object model that would be functionally rich and would provide you all the info you need. You could for instance have a Ticket and TicketColumn classes:
public class TicketColumn
{
public int Count { get; }
public int? FirstRowValue { get; set; }
public int? SecondRowValue { get; set; }
public int? ThirdRowValue { get; set; }
...
public void Reorder() { ... }
}
public class Ticket
{
public TicketColumn[] Columns
public int FirstRowCount { get; private set; }
public int SecondRowCount { get; private set; }
public int ThirdRowCount { get; private set; }
...
}
Or something similar. This is just an idea that this whole program would be better off in object oriented manner.
I have prepared a code for playing Housie with an arbitrary number of players. It informs whether anyone has won the game and terminates when someone has won the full house
The approach given to this problem goes like this;
I have prepared 10 lists. Each list has with 3 unique random numbers arranged in ascending order, ranging from 10 to 20, 20 to 30, ..., 80 to 90. Next, I have assigned the first number in 5 random lists to the top row, the second number in another 5 random lists to the middle row, and the third number in another 5 random lists to the bottom row. I have done this with the intention of not repeating the numbers, ensuring that only 5 numbers are printed on each row of the ticket, each column has it's number in an ascending order form top to bottom
I have used empty strings ' ' to be printed where there are no numbers to be printed and I have used the asterisk/star ' * ' mark to tell to the player that he/she has marked that number on that ticket!
Here's a sample ticket;
<player name>, your ticket is as follows:-
[' ' ' ' ' ' '33' ' ' '54' '66' '72' '83']
[' ' '12' '27' ' ' '45' '57' ' ' ' ' '88']
['8' '19' '29' ' ' '49' ' ' ' ' '75' ' ']
<player name>, do you want to mark?(Type 'Yes' or 'No'):
I have then asked whether the player wants to mark. Then I ensure that the player inputs an integer present in the ticket and which has also been called
It's looks like this(after marking);
The lucky number is 54!
<player name>, your ticket is as follows:-
[' ' ' ' ' ' '33' ' ' '54' '66' '72' '83']
[' ' '12' '27' ' ' '45' '57' ' ' ' ' '88']
['8' '19' '29' ' ' '49' ' ' ' ' '75' ' ']
<player name>, do you want to mark?(Type 'Yes' or 'No'): Yes
<player name>, type the number you want to mark: 54
<player name>, your ticket is as follows:-
[' ' ' ' ' ' '33' ' ' '*54' '66' '72' '83']
[' ' '12' '27' ' ' '45' '57' ' ' ' ' '88']
['8' '19' '29' ' ' '49' ' ' ' ' '75' ' ']
Notice that there is an asterisk mark beside the integer 54
It then asks whether the user wants to check if he/she has won!
The confirmatory message regarding the winners is as follows;
<player name>, do you want to check if you have won?(Type 'Yes' or 'No'): Yes
Sorry <player name>, you have not won!
Jaldi 5 Winner: None
Top row winner: None
Middle row winner: None
Bottom row winner: None
Full house winner: None
I have ensured that the numbers called don't get repeated(The main board is a list with numbers ranging from 1 to 90 and each time a number is called the sam random number is removed from the main board and while the player is given the opportunity to mark, the code ensures that the number is present in the player's ticket and the number is not present in the main board. If the player inputs a number which doesn't satisfy the above mentioned conditions, it keeps on asking until the player input a correct number
The speciality of this code is that it accepts arbitrary number of players. It initially asks you the number of players playing the game and then asks that many times the name of each individual player
Finally, the code automatically gets terminated when a player wins the full house
Here's the code I've prepared;
import random
import numpy as np
def list_of_ten(lower_limit, upper_limit):
yield list(str(number) for number in range(lower_limit, upper_limit))
def replace(numbers_list, row, collection):
for element in numbers_list:
if len(element) == 1:
collection[row][0] = element
elif int(element) == 90:
collection[row][-1] = element
else:
collection[row][int(element[0])] = element
def check_number(number, array):
row_counter = 0
column_counter = 0
for row in array:
if number in row:
for element in row:
if element == number:
return True, tuple((row_counter, column_counter))
column_counter += 1
row_counter += 1
else:
return False, None
def class_instantiation(player_count, class_to_create):
names_dict = dict()
counter = 0
while counter < int(player_count):
temporaray_input = input(f"Enter the name of the player{counter + 1}: ")
names_dict[temporaray_input.lower()] = class_to_create(temporaray_input)
counter += 1
return names_dict
def call_method(diction):
for tup in diction.items():
diction[tup[0]].display_ticket()
diction[tup[0]].mark()
def call_numeral(diction):
for tup in diction.items():
return diction[tup[0]].call_number()
class Player:
board = list(range(1, 91))
jaldi_5_winner = None
top_row_winner = None
middle_row_winner = None
bottom_row_winner = None
full_house_winner = None
def __init__(self, name):
self.name = name
self.full_list = list()
self.check_top = list()
self.check_middle = list()
self.check_bottom = list()
n1 = random.sample(next(list_of_ten( 1, 10)), 3)
n2 = random.sample(next(list_of_ten(10, 20)), 3)
n3 = random.sample(next(list_of_ten(20, 30)), 3)
n4 = random.sample(next(list_of_ten(30, 40)), 3)
n5 = random.sample(next(list_of_ten(40, 50)), 3)
n6 = random.sample(next(list_of_ten(50, 60)), 3)
n7 = random.sample(next(list_of_ten(60, 70)), 3)
n8 = random.sample(next(list_of_ten(70, 80)), 3)
n9 = random.sample(next(list_of_ten(80, 91)), 3)
n1.sort()
n2.sort()
n3.sort()
n4.sort()
n5.sort()
n6.sort()
n7.sort()
n8.sort()
n9.sort()
number_list = [n1, n2, n3, n4, n5, n6, n7, n8, n9]
self.ticket = np.array([[' '] * 9] * 3)
self.top_row = [element[0] for element in random.sample(number_list, 5)]
self.middle_row = [element[1] for element in random.sample(number_list, 5)]
self.bottom_row = [element[2] for element in random.sample(number_list, 5)]
replace(self.top_row, 0, self.ticket)
replace(self.middle_row, 1, self.ticket)
replace(self.bottom_row, 2, self.ticket)
def display_ticket(self):
print("\n\n" + f"{self.name}, your ticket is as follows:-" + "\n")
print(self.ticket[0])
print(self.ticket[1])
print(self.ticket[2])
def call_number(self):
print(f"The lucky number is {Player.board.pop(Player.board.index(random.choice(Player.board)))}!")
def mark(self):
mark_it = input("\n" + f"{self.name}, do you want to mark?(Type 'Yes' or 'No'): ")
while not mark_it.lower() == 'yes' and not mark_it.lower() == 'no':
mark_it = input("\n" + f"{self.name}, please type 'Yes' or 'No' only: ")
if mark_it.lower() == 'yes':
mark_number = input("\n" + f"{self.name}, type the number you want to mark: " + " ")
condition = check_number(mark_number, self.ticket)
while not condition[0] or int(mark_number) in Player.board:
mark_number = input("\n" + "Type a number present in your ticket which has also been called: ")
condition = check_number(mark_number, self.ticket)
if mark_number in self.ticket[0]:
self.check_top.append(mark_number)
self.full_list.append(mark_number)
elif mark_number in self.ticket[1]:
self.check_middle.append(mark_number)
self.full_list.append(mark_number)
else:
self.check_bottom.append(mark_number)
self.full_list.append(mark_number)
self.ticket[condition[1][0]][condition[1][1]] = "*" + mark_number
self.display_ticket()
winner_input = input("\n" + f"{self.name}, do you want to check if you have won?(Type 'Yes' or 'No'): ")
while not winner_input.lower() == 'yes' and not winner_input.lower() == 'no':
winner_input = input("\n" + f"{self.name}, please type 'Yes' or 'No' only: ")
if winner_input.lower() == 'yes':
if len(self.full_list) == 5 and Player.jaldi_5_winner == None:
print("\n" + f"{self.name}, you have won jaldi 5!" + "\n")
Player.jaldi_5_winner = self.name
elif len(self.full_list) == 15 and Player.full_house_winner == None:
print("\n" + f"Congratulations, {self.name}, you have won the game!" + "\n")
Player.full_house_winner = self.name
elif len(self.check_top) == 5 and Player.top_row_winner == None:
print("\n" + f"{self.name}, you have won the top row!" + "\n")
Player.top_row_winner = self.name
elif len(self.check_middle) == 5 and Player.middle_row_winner == None:
print("\n" + f"{self.name}, you have won the middle row!" + "\n")
Player.middle_row_winner = self.name
elif len(self.check_bottom) == 5 and Player.bottom_row_winner == None:
print("\n" + f"{self.name}, you have won the bottom row!" + "\n")
Player.bottom_row_winner = self.name
else:
print("\n" + f"Sorry {self.name}, you have not won!" + "\n")
print(f" Jaldi 5 Winner: {Player.jaldi_5_winner} ")
print(f" Top row winner: {Player.top_row_winner} ")
print(f"Middle row winner: {Player.middle_row_winner}")
print(f"Bottom row winner: {Player.bottom_row_winner}")
print(f"Full house winner: {Player.full_house_winner}")
no_of_players = input("How many players are going to play housie?: ")
players_dict = class_instantiation(no_of_players, Player)
while True:
if Player.full_house_winner != None:
break
else:
call_numeral(players_dict)
call_method(players_dict)
Hello might be a decade late but here is how I did it. It's in C#
using System;
namespace HelloWorld
{
class Program
{
public static void Main (String[] args)
{
for(int times=0;times<2;times++)
{
startGame();
Console.WriteLine("******************************************************************");
}
}
private static void startGame()
{
int[,] game = new int[3, 9];
int occupancyLimit = 15;
while (occupancyLimit > 0)
{
int i = getRandomNumber(3);
int j = getRandomNumber(9);
//Console.Write(i);
//Console.Write(j);
// Console.Write(game[i,j]+" ");
int data = validateAndReturnNumber(i, j, game);
if (data>0)
{
game[i, j] = data;
occupancyLimit--;
//Console.WriteLine(game[i,j]);
}
}
for (int i = 0; i < game.GetLength(0); i++)
{
for (int j = 0; j < game.GetLength(1); j++)
{
Console.Write(game[i,j] + "\t");
}
Console.WriteLine();
}
}
private static int validateAndReturnNumber(int i, int j, int[,] game)
{
//do not override existing elements in array
if (game[i,j] != 0)
{
return -1;
}
//column cannot have more then two elements
int columncounter = 0;
for(int c=0;c<3;c++)
{
if(game[c,j]!=0)
{
columncounter++;
}
}
if(columncounter>=2)
{
return -1;
}
/*
//rows cannot have more
then two cells filled in and
//rows cannot have more
then two empty cells
for(int columnIndex=0;columnIndex<=6;columnIndex++)
{
if(game[i,columnIndex+2]!=0)
{
return -1;
}
}
*/
// rows cannot have more then 5 elements
int rowcounter = 0;
for(int r=0;r<9;r++)
{
if(game[i,r]!=0)
{
rowcounter++;
}
}
//Applying, rows cannot have more then 5 elements
if(rowcounter>=5)
{
return -1;
}
//return getRandomNumberForColumn(j);
int data = 0;
Boolean isValueSet = false;
do
{
data = getRandomNumberForColumn(j);
isValueSet = isValueExistsInCol(game, i, j, data);
} while (isValueSet);
return data;
}
private static bool isValueExistsInCol(int[,] game, int i, int j, int data)
{
Boolean status = false;
for(int k=0;k<3;k++)
{
if(game[k,j]==data)
{
status = true;
break;
}
}
return status;
}
private static int getRandomNumberForColumn(int high)
{
if(high==0)
{
high = 10;
}
else
{
high=(high + 1) * 10;
}
int low = high - 9;
Random random = new Random();
return random.Next(high-low)+low;
}
private static int getRandomNumber(int max)
{
Random random = new Random();
int num=random.Next(max);
return (num);
}
}
}
$arr = new SplFixedArray(27);
for($m=1;$m<=100000;$m++)
{
in:
$final_array = array();
foreach ( $arr as $key => $val )
$final_array[ $key+1 ] = $val;
$elements_array=array();
foreach ( $arr as $key => $val )
$elements_array[ $key+1 ] = $val;
for($i=1;$i<=count($elements_array);$i++)
{
if($i==1 || $i==10 || $i==19 )
{
$elements_array[$i]=rand(1,9);
}
if($i==2 || $i==11 || $i==20 )
{
$elements_array[$i]=rand(10,19);
}
if($i==3 || $i==12 || $i==21 )
{
$elements_array[$i]=rand(20,29);
}
if($i==4 || $i==13 || $i==22 )
{
$elements_array[$i]=rand(30,39);
}
if($i==5 || $i==14 || $i==23 )
{
$elements_array[$i]=rand(40,49);
}
if($i==6 || $i==15 ||$i==24 )
{
$elements_array[$i]=rand(50,59);
}
if($i==7 || $i==16 ||$i==25 )
{
$elements_array[$i]=rand(60,69);
}
if($i==8 || $i==17 || $i==26 )
{
$elements_array[$i]=rand(70,79);
}
if($i==9 || $i==18 || $i==27)
{
$elements_array[$i]=rand(80,90);
}
}
for($k=1;$k<=5;$k++)
{
$index1=rand(1,9);
$final_array[$index1]=$elements_array[$index1];
}
$x1 = 0;
$ar1=[];
for($q=1;$q<=9;$q++)
{
if(isset($final_array[$q]))
{
$ar1[$x1]= $q;
$x1++;
}
}
loop:
if($x1 != 5)
{
$in1 =rand(1,9);
if(!in_array($in1, array_keys($ar1)))
{
$final_array[$in1]=$elements_array[$in1];
$ar[$x1]= $in1;
$x1++;
}
goto loop;
}
$z1=0;
for($q=1;$q<=9;$q++)
{
if(isset($final_array[$q]))
{
$ar1[$x1]= $q;
$z1++;
}
}
if($z1 != 5)
goto in;
for($l=1;$l<=5;$l++)
{
$index2=rand(10,18);
$final_array[$index2]=$elements_array[$index2];
}
$x2 = 0;
$ar2=[];
for($q=10;$q<=18;$q++)
{
if(isset($final_array[$q]))
{
$ar2[$x2]= $q;
$x2++;
}
}
loop2:
if($x2 != 5)
{
$in2 =rand(10,18);
if(!in_array($in2, array_keys($ar2)))
{
$final_array[$in2]=$elements_array[$in2];
$ar[$x2]= $in2;
$x2++;
}
goto loop2;
}
$z2=0;
for($q=10;$q<=18;$q++)
{
if(isset($final_array[$q]))
{
$ar1[$x1]= $q;
$z2++;
}
}
if($z2 != 5)
goto in;
for($n=1;$n<=5;$n++)
{
$index3=rand(19,27);
$final_array[$index3]=$elements_array[$index3];
}
$x3 = 0;
$ar3=[];
for($q=19;$q<=27;$q++)
{
if(isset($final_array[$q]))
{
$ar3[$x3]= $q;
$x3++;
}
}
loop3:
if($x3 != 5)
{
$in3 =rand(19,27);
if(!in_array($in3, array_keys($ar3)))
{
$final_array[$in3]=$elements_array[$in3];
$ar[$x3]= $in3;
$x3++;
}
goto loop3;
}
$z3=0;
for($q=19;$q<=27;$q++)
{
if(isset($final_array[$q]))
{
$ar3[$x3]= $q;
$z3++;
}
}
if($z3 != 5)
goto in;
DB::table('tambola')->insert(['a1'=>$final_array[1],
'a2'=>$final_array[2],
'a3'=>$final_array[3],
'a4'=>$final_array[4],
'a5'=>$final_array[5],
'a6'=>$final_array[6],
'a7'=>$final_array[7],
'a8'=>$final_array[8],
'a9'=>$final_array[9],
'b1'=>$final_array[10],
'b2'=>$final_array[11],
'b3'=>$final_array[12],
'b4'=>$final_array[13],
'b5'=>$final_array[14],
'b6'=>$final_array[15],
'b7'=>$final_array[16],
'b8'=>$final_array[17],
'b9'=>$final_array[18],
'c1'=>$final_array[19],
'c2'=>$final_array[20],
'c3'=>$final_array[21],
'c4'=>$final_array[22],
'c5'=>$final_array[23],
'c6'=>$final_array[24],
'c7'=>$final_array[25],
'c8'=>$final_array[26],
'c9'=>$final_array[27],
]);
}

Resources