📜 ⬆️ ⬇️

nanoCAD and side bows, or program Reversi for the CAD platform

Some time ago, an article about programming under nanoCAD was published on Habré in the Nanosoft blog. And on the same day, an article about “Reversi programming in Python” ran through. A week later, Reversi was written in Silverlight , a little later in Tcl / Tk . It was safe to say that the game Reversi went to the people. Just at that time I was studying the possibilities of scripts under nanoCAD. But learning required practice. And I thought - why am I worse? And I decided to write a kind of "nano-boyan." So 3D Reversi appeared.

Title image

Script capabilities of CAD platforms have always attracted me. Using the script, you can screw your own functionality to a large system. Thereby, using CAD not only as developers have “sewn up” into it, but also for my subjective purposes.

For the practice of studying the symbiosis of nanoCAD and JScript, I began to write a "frivolous" script, under the CAD system.
')

Start


I divided the development of the game mentally into three parts: the development of the game field (interface), the development of interactivity (interaction with the user), and the game algorithms themselves.

To develop the playing field, I needed to create objects in the nanoCAD model space. Without documentation, all attempts to write something for something are probably doomed. And the first thing I did - I began to look for a description of objects and functions. I asked Google (almost like a song is sung) and received a large number of links to various sites describing the AutoCAD object model. For example this site.

Creating objects


Objects are added using the ThisDocument.ModelSpace collection. Immediately make a reservation that I wrote in JScript, because as I program in C ++, the syntax of JS is closer to me than the syntax of VB Script.

The field consists of 64 cells, a grid and chips. I made the grid and chips with bulky shapes. And for the cells of the field, I used hatching.

// ( shag ).
var polyline;
var RefPoly = new Array(0,0,0, shag,0,0, shag,shag,0, 0,shag,0);

polyline = ms.AddPolyline(ut.CreateTypedArrayFromJSArray(5, RefPoly));
polyline.Closed = true;

// :
hatch = ms.AddHatch(1,"SOLID",false,0);
hatch.AppendOuterLoop(polyline);


Then I multiplied the cells and put them in their places.

Next I need borders and game chips. Just copy the game written in Python, it was not interesting. Needed its own zest. Since nanoCAD has the ability to display objects in space, this highlight was the volume of the board and gaming chips. Therefore, I made curbs and tiles 3DMesh objects.

Each edge is just a rectangle. And each chip is a sphere.
Object objects are objects of type 3DMesh. They are created using the Add3DMesh (...) ModelSpace collection. This is a network of size M on N cells. To create it, you need to specify in the array the coordinates of all vertices of the network. Along the rows: first points of the first row, then the second, and so on until M.

 //    : var mesh = new Array(); var n = 0; for (i=-1;i<2; ++i) for (j=0;j<9; ++j) { mesh[n] =0; mesh[++n]=shag*j; mesh[++n]=shag*i/10; n++; } //  ,  ,    YZ. var mesh3d = ms.Add3DMesh(3,9,ut.CreateTypedArrayFromJSArray(5,mesh)); 

Then I added thickness to the ribs so that the ribs did not disappear when viewed from above.

It was more difficult to build a sphere than edges. I had to remember the analytical geometry of the times of the 1st course. I did not go to the library. I went to Wikipedia and found out how spherical coordinates are expressed via Cartesian.
 var Vertexs = new Array(); var idx =-1; var r =22; for(j=0; j <= 20; ++j) for(i=0; i < 20; ++i) { beta = Math.PI / 19 * j; alfa = 2 * Math.PI / 20 * i; Vertexs[++idx] = 25 + r*(Math.cos(alfa)*Math.sin(beta)); Vertexs[++idx] = 25 + r*(Math.sin(alfa)*Math.sin(beta)); Vertexs[++idx] = r*Math.cos(beta); } fishka_b = ms.Add3DMesh(20,20,ut.CreateTypedArrayFromJSArray(5,Vertexs)); 


As a result of these actions, the following playing field has turned out:
picture 1

User interaction


The next step was to organize the interaction of the script with the user. You need to ask where the player wants to put his chip. This is what the GetEntity () function does.

 // ,   ,   ,    1   while (hatch==null) { ut.GetEntity(RefPoly,null," "); if (RefPoly.length == 1 && RefPoly [0].EntityName == "AcDbHatch") { //     –   .    . if (RefPoly[0].Hyperlinks.Count > 0) hatch = RefPoly [0]; } x = parseInt (hatch.Hyperlinks.Item(0).URLDescription); y = parseInt (hatch.Hyperlinks.Item(0).URLNamedLocation); } 

There is a trick here: in order not to calculate the coordinates of each of the hatchings, when creating each of them, I laid out the location information on the field.

// i, j –
hatch.Hyperlinks.Add("xy",i.toString(),j.toString());

// , :
x = parseInt (hatch.Hyperlinks.Item(0).URLDescription);
y = parseInt (hatch.Hyperlinks.Item(0).URLNamedLocation);


I will not dwell on the algorithms in more detail. I did not write super smart AI. And I made the decision function from the Reversi on Python source. I must say that I have not seen Python before this day even once. Everything is quite readable. Adaptation to JScript took me 10 minutes.

Nuances and Tricks


Now about the nuances of scripting under the NanoCAD.
I don’t know exactly how in VBS, but in JScript all variables are passed to functions by value, not by reference. What does it mean? This means that if you specify a JScript variable when calling a method and expect that the result will return to you after the execution of the method, then you will be upset - this will not happen. The variable will not change. So, for example, with the GetEntity method (Object, PickedPoint [, Prompt]). The first parameter in it is a variable, through which the set of selected objects is returned. But in JS it does not work. How to bypass this restriction? It is necessary to transfer an array instead of a variable.

var RefPoly = new Array();
ut.GetEntity(RefPoly,null," ");
var entity = RefPoly[0]; // .


The second important point is that the methods associated with the coordinates (creating objects, for example) do not accept script arrays. Since JS and VBS languages ​​are weakly typed, their arrays can contain elements of different types. It is unacceptable. To cast to a typed array, use the functions of the Utility object CreateTypedArray (varArr, Type, ParamArray) and CreateTypedArrayFromJSArray (Type As Long, varJSArray). Here Type is an indication of the type of the elements of the array, and JSArray is the array itself.

// js
var RefPoly = new Array(0,0,0, shag,0,0, shag,shag,0, 0,shag,0);

// , , TypedArray.
var polyline = ms.AddPolyline(ut.CreateTypedArrayFromJSArray(5,RefPoly));


Running script


To properly display the elements of the game you need to set the style of lighting models. The style is set in the menu View -> Style. I set the exact style without showing the edges.
To run the reverse, we write the command “JS” in the command line of the nanoCAD. And then we specify the full path to the nanoReversi.js script.

Result


After three evenings, I reached the goal I had set myself - the game Reversi earned under nanoCAD.
picture 2

In reversi isomerism look much more unusual. I was absolutely pleased.
picture 3

Despite the fact that I wrote a reverse that is called “Just for fun”, the script demonstrates the capabilities of ActiveX Automation nanoCAD. And if you remember that you can use other ActiveX servers in scripts, for example ADO to connect to databases, the scripting tasks are no longer as serious as Reversi.

The demo script can be downloaded here .

Source: https://habr.com/ru/post/90742/


All Articles