编程农场

编程农场

评价数不足
Codes for the Coding Beginner
由 dBlueFalcon 制作
*DUE TO STILL GOING THROUGH THE GAME, THIS IS A WIP. *


I have never created, learned, played, or used "code" before I purchased this game.

That being said, if you want to see my own approaches (codes) that I created (without researching the "solutions' elsewhere) then feel free to compare, critic, grade, insult, or otherwise comment on my codes!

I am pretty proud of my solutions, and I feel that they are "bug-free", but if you happen to run into any issue(s) using my codes, PLEASE let me know! I'm certain that my codes (custom functions, variables, etc.) will not be friendly to all other player's custom content.
2
   
奖励
收藏
已收藏
取消收藏
BEGINNER TIPS
*** I will dive "deeper" into each topic in further chapters. Right now, I'm just giving basic information/tips.***

1. VARIABLES (ONCE UNLOCKED) ARE YOUR FRIENDS!

If you are familiar with variables in algebra, this game is using almost the exact same thing (I say "almost" because this game allows variables to equal words, function names, etc. which eventually return with their own values, including "True", "False", and "None" values.

However, if you don't like algebra, that's OK, because another way to look at this portion of the game-play is like you're creating your own dictionary (words, definitions, etc.)

Throughout this game (via Variables, etc.) you're basically just defining things with a custom acronym, word, or phrase (the latter of which would need to be separated using "_" instead of a "space" character; for example: "this_is_an_example".)

2. FUNCTIONS (ONCE UNLOCKED) ARE VERY, VERY, VERY USEFUL IN SAVING YOU TIME!!

If you want to go far in this game, and do so quicker than the alternative, then "functions" should be a term you are not only familiar with, but they should be a function of the game you use often (pun intended!)

Functions basically contain as many actions, commands, local variables, etc. that you want to place "inside them". Once that is done, you can perform ALL of those actions, etc. simply by calling the function's name (for example, " harvest() * is actually a built-in function for the game, and it does exactly what it seems like it would do; it harvests any ripe resource (that the drone is currently flying over) that is capable of being harvested. So, if your drone is over a grassy "square", calling harvest() would reap the hay from the grassy block and send it to your stored resources.

This can quickly become not only overwhelming (until you experiment , learn, etc.) but also VERY rewarding.

One way I use functions to make my life easier is by creating 'global' shortcuts that I can use throughout the code file (as well as with other files, but that's another chapter...)

For instance, I have a function called "reap_and_water()", or "raw()" for short, if you don't like long-winded function titles.

This code is actually very easy to make (meaning that if you don't like the example given below, make your own!) but it saves you a lot of time when you are learning new crops and needing to adapt to their own needs, etc.

The function "reap_and_water()" could look something like this:

def reap_and_water(): if can_harvest(): harvest() use_item(Items.Water)

however, once you get far enough in the game, you may need/want to be a little more complicated with this function. Below is another example, but somewhat more complex:

def reap_and_water(): if can_harvest(): harvest() if get_water() < .80: use_item(Items.Water) else: if get_entity_type() == None: pass

Alright, so some people may disagree with my choice to water the square before planting a new crop, but there's actually a good reason behind making this decision.

REASON:
because I said so...

OTHER, LESS IMPORTANT REASON:
Using water once does not fully saturate the ground in that square. It takes multiple water 'deliveries' to fully saturate the ground. Therefore, the more you water, the more fertile the ground will be. There is actually no downside to this (other than using water, if you're a water hoarder...) because the following things will NOT reset or negatively impact the water level:

tilling does not change or erase the water level.
planting AFTER watering does not change or erase the water level.

That's why I water after reaping (as well as before planting, but that's just me so I can make sure the water levels are good in every square.)

BUT ANYWAY, BACK TO THE TOPIC AT HAND!

The above-listed functions took lots of characters, time, typing, thought process, etc.

HOWEVER, after making the function, you can simply type "reap_and_water()" and the entire function (actions, etc.) will trigger after the function is called. That saves me from having to input the above-listed code EVERY time I want to harvest and reap a world square.

3. DID I MENTION THAT VARIABLES ARE YOUR FRIENDS???


Seriously though, variables are pretty complex. For example, you can assign (define) a variable within a function, and that variable will compute differently than if you use the exact same variable outside of the function (unless the 'global' variable is called/used in the function, then scratch everything I just said (lol, like I said, complex.)

An example is listed below:

x = 0 def get_x(): x = get_pos_x()

the first-listed "x" (otherwise known as a "variable", since it's meaning, result, etc. can change based on the provided input) computes to the number zero (because I told it to.) However, the SECOND "x" variable is assigned/defined inside the function "get_x()". In that function, I simply define "x" as being the same thing as "get_pos_x()". When the function begins/triggers, the system will actually check what "x" position the drone is in. After it gets that result, the second "x" variable is made to be EQUAL to that value.

For example, if your drone is in position "2" on the "x" coordinates, then "x" would equal 2. Thus the function's variable translates to "x = 2" instead of "x = get_pos_x()".

I won't go much further into this just yet, but it can later get VERY complex when you create functions that change the variable multiple times within the same function. A simple "x = x +1" is a good example of an always-changing variable.

This concludes my introduction, or rather, "beginner tips". I hope you all are enjoying this game as much as I am! I have been blown away with how easily I am able to learn the game's pseudo Python coding language, and think of creative ways to become more efficient as a farming drone!
Variables May Vary Very Much in their Many Varying Varieties
Sorry for the redundantly-repetitive title... (dang it, I did it again!)

Variables are simply the same thing as Algebraic variables (something that equals something else, and is capable of changing itself as well.)

These are extremely useful in not only saving time while writing code, but also in performing mathematical equations (including the ones that can change in a second depending on how each variable's value changes.)

A simple example of this is listed below:

x = 0 while True: move(East) x = 0 + 1

in this code, (especially if used in a "while" loop) the value of "x" continues to change in a predictable and reliable manner. Basically, "x = 0" outside of the loop (or rather, before the loop begins.) Once the loop begins, however, each time the drone moves East, the "x" increases in value (increasing by 1.)

A different (though somewhat similar) "x" variable is listed below:

x = get_pos_x() while True: while x != 0: move(West) x = x - 1

this "x" variable is more adaptable in the sense that it can detect "where" it is to begin with.

For instance, if the drone was on/over position "4" on the x-coordinates, then x = 4. Yet almost immediately, the value of "x" begins to decrease with each loop, due to the variable equation "x = x - 1".

This code would work in getting your drone to be on the "x0" coordinate/square. The below-listed codes are actually some of my favorites because of their usefulness in a lot of my different codes:

global x global y x = get_pos_x() y = get_pos_y() # ========== GET_X ========== def get_x(): global x x = get_pos_x() return x # ========== GET_Y ========== def get_y(): global y y = get_pos_y() return y # ======= GET_XY ======== def get_xy(): global x global y return x, y # ===== STEP(DIR) ===== def step(dir): global x global y if dir == East: move(East) x = (x + 1) % ws elif dir == West: move(West) x = (x - 1) % ws elif dir == North: move(North) y = (y + 1) % ws elif dir == South: move(South) y = (y - 1) % ws # ========== GO_TO ========== def go_to(tx, ty): global x global y dx_right = (tx - x) % ws dx_left = (x - tx) % ws if dx_right <= dx_left: int = dx_right for _ in range(int): step(East) else: int = dx_left for _ in range(int): step(West) dy_up = (ty - y) % ws dy_down = (y - ty) % ws if dy_up <= dy_down: int = dy_up for _ in range(int): step(North) else: int = dy_down for _ in range(int): step(South) return x, y

basically, this code (though likely more complicated than a senior coder, dev, etc.) allows me to, at any point call (for example) "go_to(0,0)" and the drone will move to those coordinates (which are 0 , 0; x coordinate zero and y coordinate zero.)

I have found that, though it is often dependent on inputting the coordinates by yourself, it also allows the following code to work, perfectly "scaling" to any world size automatically:

for yy in range(ws): for xx in range(ws): go_to(xx, yy)

that 'simple' code now automatically travels each world square one time, no matter what size world you have.

Another way you can use (and honestly, should be using) variables is by shortening some of the functions that result in simple number values or "True", "False", or "None" values. For example, I like my functions to have longer names so that, should I need to troubleshoot functions that I made a while ago, I know what the intended purpose was. I then just use a simple variable to "shortcut" that function's result.

Below is an shortened example of what I mean, (aka, not listing all of the items):

tct = testing_crop_type def testing_crop_type(): carrot = Entities.Carrot if get_entity_type() == carrot: return(carrot) tct()

this means that, when multiple items and variables are listed, it would correctly return with whatever entity it detects underneath the drone. To clarify, "carrot" is the variable, and that variable is made to equal the actual carrot entity. Therefore, instead of having to type "Entities.Carrot" every time I was to refer to the game's carrot item, all I have to type "carrot" and the game translates that to the item itself. Additionally, as you can see i made a variable "tct" which equaled the phrase/words "testing_crop_type", and as long as you leave the "()" out of both portions of the variable, then you can call the function using the shorter variable by immediately following it with "()".

This is just a brief overview of variables. I am so excited to continue experimenting and learning new methods, etc. for the variables capabilities in this game.
Functions and Importing Files
This chapter is not able to be efficiently discussed without also talking about one of the "upgrades" which assist functions' functionality in the game (there I go with the puns again...)

It may be helpful to see functions as the definitions of an action. This is initially easy to comprehend since each function is assigned/created by "def" which means "define".

for instance, the code below is an example of a function:

def example(): while get_pos_x() != get_world_size(): x = get_pos_x() move(East) x = x + 1

the function name/title is "example()", and the portion of the name which tells the system to trigger a function (as well as knowing the name of the function itself) is the "()". The function, "example()" is defined as performing the following actions (in the example above): 1. get the current "x" position in the world, and assigned it's value to the variable "x". 2. move East one time. 3. change the local "x" variable in accordance with moving east one time. All of these things happen ONLY while the drone is not on/over the last x position for the current world size.(meaning that it will not move east if it is at the easternmost side of the world.)

Another thing to know is that you can actually "call" (activate) another function within a different function, however, this is contingent on the current file (the minimize-able/close-able window in which you are typing the current code, etc.) having access to any and all functions and variables being activated/used.

One example is listed below, after which we will get into "files" and how the "import" upgrade is SUPER helpful in saving space, troubleshooting code's incompatibilities with one another, etc.

def reap(): if can_harvest(): harvest() def water(): if get_water() < .80: use_item(Items.Water) def reap_and_water(): reap() water()

The first two functions are combined and utilized in the third/last function. This is possible as long as the "master" function has access to the lesser functions.

FILES, AND THEIR USES (LIKE, IMPORTING):

Alright, so... (SPOILER ALERT, SPOILER WARNING, DO NOT PASS GO, DO NOT COLLECT $200!)

Files (and importing) are important to purchase/upgrade, and here's why:

Files are the windows you type code in. That's obvious. But importing is less-so...

Importing allows the ability to jump from one file to another (similar to jumping from one function to another, as mentioned above.)

so if I have one file (window) that has a "reap()" function, I would NOT be able to use that in a totally different file unless I copy-and-paste it into the new file, OR "import" it into the new file.

Below are some examples of importing files (via their file names) into another file:

from example import * from example import reap() example.reap() import example

the first-listed line allows the import of all variables (global, etc.) to be imported (copied and used, essentially) in the new file.

the second-listed line allows a specific function to be imported into the new file. For this example, the new file can now call on the function "reap()" by first listing the file name, followed by a period character/symbol, then listing the function name. i.e. "example.reap()"

the last-listed line allows the entire file to be imported (but this may be a bad choice, if you are using similar function names, variables, etc. for different files. For example, if I import a global "x" variable from the example file, and also have a global "x" variable in my current file, then the global "x" will conflict with itself (or rather, assume the newer value assigned to it, thus potentially conflicting with one of the files, if not both.) The same can be said for functions such as "reap()" if, for example, you have a "pumpkin" file that has it's own reap() function (for obvious reasons, if you know about pumpkins yet.) there can be a good reason to change a function's actions for a specific file, while not wanting to change the name itself. Just keep this in mind if you find yourself doing this.

Me, personally? I simply name my similar-but-different functions to be, well, similar but different...

for example: my pumpkin "reap" could be called "reap_p()" for reaping pumpkins, or maybe the "x" variable could be assigned/created as "pum_x" instead of simply "x". These are just examples, of course.

CODE OPTIONS
In this chapter, I will simply be providing some of the codes I made during my play through. Keep in mind that I made these: 1. without any prior coding experience, and 2. without researching any "veteran" code solutions made by persons more capable than yours truly.

Below is my "sunflower" file, which I have found effective in only harvesting the highest measurement in the field during that sweep (which is the intended challenge/change provided by the sunflower crop.)


HERE YOU GO!


import globals from globals import * from mov import * import mov from paw import * import paw x = mov.get_x() bx = x y = mov.get_y() by = y m = measure() bm = m def measuring(): global x global bx global y global by global m global bm # Current position & measurement x = mov.get_x() y = mov.get_y() cur_m = measure() # If we're at (0,0) and it's empty, plant once, then re-measure if (x, y) == (0, 0): if cur_m == None: paw.paw_sunflower() cur_m = measure() # Normalize None -> 0 for safe numeric comparison if cur_m == None: cur_val = 0 else: cur_val = cur_m if bm == None: best_val = 0 else: best_val = bm # Update "best" if improved if cur_val >= best_val: bm = cur_val bx = x by = y return (bx, by) def farm_sunflower(): global x global bx global y global by global m global bm # Scan a 5x5 area (0..4, 0..4) for yy in range(ws): for xx in range(ws): mov.go_to(xx, yy) soil.soilmeasuring() if get_entity_type() == None: paw.paw_sunflower() # Go reap the best spot found mov.go_to(bx, by) reap_best() def reap_best(): global x global y global bx global by global m global bm mov.go_to(bx, by) if measure() == bm: harvest() m = 0 bm = 0 x = 0 bx = 0 y = 0 by = 0

now, as you can see, this file is dependent on several other files in order to work effectively. Obviously, I've already provided the "mov" file to you in an earlier chapter. But, in order to encourage you to simply use this code as inspiration and not a cheat, I am intentionally not going to provide the necessary files (that I created) which this file is dependent on.

What I can say is that this file (as you can tell based on reading the functions, etc.) and its dependent files, variables, etc. are capable of planting a field of sunflowers while measuring/scanning each one. After it has measured the whole field, it then knows which square had the best sunflower measurement. It will go to that square and harvest that sunflower. It will then continue to do this (planting on empty squares, scanning, harvesting the best sunflower) forever (until I stop it, of course.)



NEXT

The next code I will provide (without fully "providing") is for the pumpkin crop. This crop is unique in that you will get a LOT more pumpkins if you let it grow to it's max size (the current world size) before you reap it.

While studying this crop, I noticed that it generates a random code for every pumpkin, and the numbers are not predictable. Therefore the solution I came up with was essentially this:

scan each pumpkin. Make sure pumpkins are being planted. If the whole field has the same "measurement" that must mean that it's a single BIG pumpkin. Harvest...

Here's the code!

from globals import * import globals from mov import * import mov from paw import * import paw from reap import * import reap global x global y x = get_pos_x() y = get_pos_y() mov.go_to(0,0) def farm_pumpkin(): global x global y x = get_pos_x() y = get_pos_y() # FIRST 'SEED' TO COMPARE TO OTHERS: reap.reap_and_plant_pumpkin() measure() seed1 = measure() for yy in range(ws): for xx in range(ws): measure() seed2 = measure() if seed2 == seed1: if get_entity_type() == None: reap.reap_and_plant_pumpkin() else: pass if seed2 != seed1: reap.reap_and_plant_pumpkin() mov.go_to(xx, yy) if get_entity_type() == None: paw.paw_pumpkin() if seed1 == seed2: harvest() while True: farm_pumpkin()

Both of these crops' codes work perfectly for me. So, if you run into any issues, that is simply because you likely don't have the same function(s), variable(s), etc. that I do (which I imported from other files.)

I SUPER appreciate you guys for reading so far! I definitely intend on updating this with each new crop/solution that I come across. Let me know if you have any advise, comments, complaints (except for the lack of my other files, that is intentional) and GOOD LUCK!