A Turing machine is actually similar to brainfuck.

It has a tape (endless array) just like brainfuck does, although rather than integers in each cell, there is a user defined set of symbols. The simplest possible set of symbols would be "0" and "1", although you can have many more, including say a set of 256 integers like brainfuck.

Each "instruction" (state) lets you specify what symbol to write, a "move left" or "move right" command, and what the next instruction will be (goto style), except that you get to specify the symbol to write, the move left or right, and the command to jump to. You specify all of those things independently for each and every possible symbol that might be at the current tape position. You also have the option of specifying no next command, in which case the machine halts.

So to do the equivalent of "+" in brainfuck, you would specifying that is "3" is present you write "4", if "4" is present you write "5", etc. You specify for all of these a "no movement" option if your formulation of Turing machines allow that (otherwise, you translate it to a move right, followed by an extra state that writes back the value read and move left). You specify that for all possible values you read you will jump to the the "next" instruction.

For the equivalent of a "]" instruction, you would specify to write back the symbol you just read, no movement, and if the value you read was a zero, you jump to the "next" instruction, otherwise you jump back to the command right after the corresponding "[" instruction.

You would probably want to design a compact way of specifying this, the mathematical formulation of Turing machines only cares that a mapping exists, not how you chose to specify that mapping. Actually specifying all the mappings explicitly would take up a lot of room, and be hard to understand. This is especially true if you have a lot of distinct symbols that can appear on the tape of your Turing machine.

Unlike brainfuck, a Turing machine has no system for reading input or writing output, except the tape itself. For input you need to prespecify any needed values on the tape, and for output, you read the tape once you reach the end. This means a Turing machine cannot be interactive. You cannot enter input that depends on the what it previously wrote as output. To do interactivity, you instead have a group of Turing machines, where each one stops when they want input, you read the output, and modify the tape to specify the input, and then start the next Turing machine on that tape. (With some clever work, it is possible for it to be the same Turing machine every time, by having a symbol at the current represent the state (instruction) to resume at, having it write a value there before halting, and read that value when starting up, and jump to said state.

I've outlined one approach for handling non-interactive I/O below in brainfuck-esque style below. It is complicated and not super pretty, but it does work.

-----------------------

One useful approach lets you simulate having multiple tapes: one for computation, one i/o. You might interleave cells, so a group of 3 cells consists of one cell for computation purposes, one cell that represents i/o, and a last cell where you can store a value that indicates if this cell cluster is the "origin" one, if this cell cluster represents the current Input position, if it represents the current output position, and if it represents the current computation position. 4 orthogonal flags, so 16 distinct symbols can be used used to indicate any combination of these flags.

Perhaps input uses i/o cells to the right of the origin position, and output uses i/o cells to the left of the origin position (and thus "backwards"), with computation always limiting itself to cell to the right of input position (for simplicity).

Then to implement an output current cell equivalent brainfuck command, you would create 256 distinct versions of the following sequence: "move to current locator cell. Mark this as the current computation position. While the locator cell indicates this is not the output cell position, move left in groups of 3 cells. when you find the current output position. Unmark it as current output, move left 3 cells, mark as current output, move to the IO cell, and write the value (this is the whole reason why this loop needs to exist 256 times, as a way to remember the value to write while moving to the output position)." Now all 256 of them can share the following logic: "Move back to locator cell. While current position is not marked as the computation position, move right in groups of 3 cells. When you finally reach the computation position, unmark it as such (we don't bother to maintain this mark at all times, only when doing input or output), and move to the computation cell." Now can move onto the next logical instruction.

Notice that all of that would logic would exist for each individual output command. Nobody ever said simulating a multi-tape turning machine on a classical single tape one is at all efficient.

Input would be: mark current cell as computation position. Move left until you find origin (if you find the current input position along the way, you can skip to the logic for that part), move right until you find current input position. Move marker to the right by one group, read the i/o value. Now 256 copies of moving left until you find the origin (if you happen to find the computation position, you can shortcut to that logic), followed by moving right until you find the computation position. Unmark the computation position, move to computation cell for this cluster, and write the value. (Again why you need 256 copies of this loop).